• Educational Codeforces Round 20


    Educational Codeforces Round 20 

    A. Maximal Binary Matrix

    直接从上到下从左到右填,注意只剩一个要填的位置的情况

    view code
    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 111;
    bool vis[MAXN][MAXN];
    void solve(){
        int n, k; cin >> n >> k;
        if(n*n<k) cout << -1 << endl;
        else{
            for(int i = 1; i <= n and k; i++) for(int j = 1; j <= n and k; j++){
                if(vis[i][j]) continue;
                if(k==1){
                    if(i!=j) continue;
                    vis[i][j] = true;
                    k--; break;
                }
                vis[i][j] = vis[j][i] = true;
                if(i==j) k -= 1;
                else k -= 2;
                if(!k) break;
            }
            for(int i = 1; i <= n; i++){
                for(int j = 1; j <= n; j++) cout << (vis[i][j] ? 1 : 0) << ' ';
                cout << endl;
            }
        }
    }
    int main(){
        #ifndef ONLINE_JUDGE
        freopen("Local.in","r",stdin);
        freopen("ans.out","w",stdout);
        #endif
        solve();
        return 0;
    }
    

    B. Distances to Zero

    把所有(0)的位置记下来然后二分找最近位置即可

    view code
    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 2e5+7;
    void solve(){
        ____();
        int n;
        cin >> n;
        vector<int> vec(n);
        for(int &x : vec) cin >> x;
        vector<int> zeropos;
        for(int i = 0; i < n; i++) if(!vec[i]) zeropos.push_back(i);
        for(int i = 0; i < n; i++){
            auto p = lower_bound(zeropos.begin(),zeropos.end(),i);
            int ret = MAXN;
            if(p!=zeropos.end()) ret = *p - i;
            if(p!=zeropos.begin()){
                p--;
                ret = min(ret,i-*p);
            }
            cout << ret << ' ';
        }cout << endl;
    }
    int main(){
        #ifndef ONLINE_JUDGE
        freopen("Local.in","r",stdin);
        freopen("ans.out","w",stdout);
        #endif
        solve();
        return 0;
    }
    

    C. Maximal GCD

    考虑枚举(g=gcd(A)),由于要递增,所以填的方式为(g,2g,3g,cdots kg+l)

    显然要满足(gmid sum A_i),找最大的满足条件的(g)即可

    view code
    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    typedef long long int LL;
    
    void solve(){
        LL n, k;
        cin >> n >> k;
        if(k>1e7 or (k+1)*k/2>n) cout << -1 << endl;
        else{
            vector<LL> f;
            for(LL i = 1; i * i <= n; i++){
                if(n%i) continue;
                f.push_back(i);
                if(i!=n/i) f.push_back(n/i);
            }
            sort(f.begin(),f.end());
            LL tot = (k + 1) * k / 2;
            LL g = 1;
            for(auto d : f){
                if(tot * d > n) break;
                g = max(g,d);
            }
            vector<LL> ret;
            for(int i = 0; i < k; i++){
                ret.push_back((i+1)*g);
                n -= (i+1)*g;
            }
            ret.back() += n;
            for(auto x : ret) cout << x << ' ';
            cout << endl;
        }
    }
    int main(){
        #ifndef ONLINE_JUDGE
        freopen("Local.in","r",stdin);
        freopen("ans.out","w",stdout);
        #endif
        solve();
        return 0;
    }
    

    D.Magazine Ad

    把所有串按空格和横杠分开,得到一些短的串,每个串的权值为长度,问题转化为把(n)个数分成最多(k)组,求权值最大的组的最小值,二分即可

    view code
    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 1e6+7;
    int k;
    void solve(){
        ____();
        string s;
        cin >> k;
        cin.get(); getline(cin,s);
        s.push_back('-');
        // binary search
        vector<int> pos;
        pos.push_back(-1);
        for(int i = 0; i < s.length(); i++) if(s[i]=='-' or s[i]==' ') pos.push_back(i);
        vector<int> seg;
        for(int i = 1; i < pos.size(); i++) seg.push_back(pos[i] - pos[i-1]);
        seg.back()--;
        auto check = [&](int m){
            int cnt = 0, tot = 0;
            for(int i = 0; i < seg.size(); i++){
                if(seg[i]>m) return false;
                if(tot + seg[i] <= m) tot += seg[i];
                else{
                    cnt++;
                    tot = seg[i];
                }
            }
            cnt++;
            return cnt <= k;
        };
        int l = 1, r = s.length();
        while(l<=r){
            int mid = (l + r) >> 1;
            if(check(mid)) r = mid - 1;
            else l = mid + 1;
        }
        cout << l << endl;
    }
    int main(){
        #ifndef ONLINE_JUDGE
        freopen("Local.in","r",stdin);
        freopen("ans.out","w",stdout);
        #endif
        solve();
        return 0;
    }
    

    E. Roma and Poker

    考虑(DP)(dp[i][j])表示到第(i)个位置赢和输的差值为(j)的情况下的上一个状态

    转移的时候注意不能从差值的绝对值为(k)的状态转移过来

    最后倒推回去输出答案就好了

    view code
    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 1e3+7;
    const int D = 1e3+3;
    const int INF = 0x3f3f3f3f;
    int f[MAXN][MAXN<<1];
    
    int n, k;
    char s[MAXN];
    void solve(){
        ____();
        cin >> n >> k >> s + 1;
        memset(f,0x3f,sizeof(f));
        f[0][D] = -1;
        for(int i = 1; i <= n; i++){
            if(s[i]=='L' or s[i]=='?'){                                 // lose
                for(int j = D - k + 1; j <= D + k - 1; j++){
                    if(f[i-1][j]==INF) continue;
                    f[i][j-1] = j;
                }
            }
            if(s[i]=='W' or s[i]=='?'){                                 // win
                for(int j = D - k + 1; j <= D + k - 1; j++){
                    if(f[i-1][j]==INF) continue;
                    f[i][j+1] = j;
                }
            }
            if(s[i]=='D' or s[i]=='?'){
                for(int j = D - k + 1; j <= D + k - 1; j++){
                    if(f[i-1][j]==INF) continue;
                    f[i][j] = j;
                }
            }
        }
        if(f[n][D+k]==INF and f[n][D-k]==INF) cout << "NO" << endl;
        else{
            int u;
            string ret;
            if(f[n][D+k]!=INF) u = D + k;
            else u = D - k;
            for(int i = n; i >= 1; i--){
                if(u - f[i][u] == 0) ret.push_back('D');
                else if(u - f[i][u] == 1) ret.push_back('W');
                else ret.push_back('L');
                u = f[i][u];
            }
            reverse(ret.begin(),ret.end());
            cout << ret << endl;
        }
    }
    int main(){
        #ifndef ONLINE_JUDGE
        freopen("Local.in","r",stdin);
        freopen("ans.out","w",stdout);
        #endif
        solve();
        return 0;
    }
    

    F. Coprime Subsequences

    (f(n))表示组合的(gcd=n)的方案数

    (F(n))表示组合的(nmid gcd)的方案数

    那么(F(n) = sum_{nmid d}f(d))

    根据莫比乌斯反演,(f(n) = sum_{nmid d}mu(frac dn)F(d))

    我们要求的答案就是(f(1))

    容易发现如果有(x)个数的因子有(d)那么(F(d) = 2^x-1)

    那么我们就能很容易算出(f(1))

    view code
    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MOD = 1e9+7;
    const int MAXN = 1e5+7;
    int n, prime[MAXN], pri_cnt, mu[MAXN], cnt[MAXN], pw[MAXN];
    bool npm[MAXN];
    
    vector<int> ds[MAXN];
    void sieve(){
        mu[1] = 1;
        for(int i = 2; i < MAXN; i++){
            if(!npm[i]) prime[++pri_cnt] = i, mu[i] = -1;
            for(int j = 1; i * prime[j] < MAXN; j++){
                npm[i*prime[j]] = true;
                if(i%prime[j]==0){
                    mu[i*prime[j]] = 0;
                    break;
                }
                mu[i*prime[j]] = -mu[i];
            }
        }
        for(int i = 1; i < MAXN; i++) for(int j = i; j < MAXN; j += i) ds[j].push_back(i);    
        pw[0] = 1;
        for(int i = 1; i < MAXN; i++) pw[i] = pw[i-1] * 2 % MOD;
    }
    
    
    void solve(){
        ____();
        sieve();
        cin >> n;
        for(int i = 1; i <= n; i++){
            int x; cin >> x;
            for(int d : ds[x]) cnt[d]++;
        }
        int ret = 0;
        for(int i = 1; i < MAXN; i++) ret = (ret + mu[i] * 1ll * (pw[cnt[i]] - 1)) % MOD;
        cout << (ret + MOD) % MOD << endl;
    }
    int main(){
        #ifndef ONLINE_JUDGE
        freopen("Local.in","r",stdin);
        freopen("ans.out","w",stdout);
        #endif
        solve();
        return 0;
    }
    

    G. Periodic RMQ Problem

    由于范围比较大,考虑离散化坐标,为了能找到最小值,需要在离散化坐标相邻的两点中间额外加入一个区间最小值的点,这个点的值可以用(ST)表来找,加的点的值根据两点实际坐标的距离和位置稍微分类一下就好了,然后就很好搞了

    view code
    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 6e5 + 7;
    const int INF = 0x3f3f3f3f;
    int n, k, A[MAXN][20];
    struct Qs{ int type, l, r, x; }Q[MAXN];
    struct SegTree{
        #define ls(rt) rt << 1
        #define rs(rt) rt << 1 | 1
        int minn[MAXN<<2], l[MAXN<<2], r[MAXN<<2], lazy[MAXN<<2];
        #define pushup(rt) minn[rt] = min(minn[ls(rt)],minn[rs(rt)])
        void build(int L, int R, vector<pair<int,int> > &vcc, int rt = 1){
            l[rt] = L, r[rt] = R;
            if(L + 1 == R){
                minn[rt] = vcc[L].second;
                return;
            }
            int mid = (L + R) >> 1;
            build(L,mid,vcc,ls(rt)); build(mid,R,vcc,rs(rt));
            pushup(rt);
        }
        void pushdown(int rt){
            if(!lazy[rt]) return;
            lazy[ls(rt)] = lazy[rs(rt)] = minn[ls(rt)] = minn[rs(rt)] = lazy[rt];
            lazy[rt] = 0;
        }
        void modify(int L, int R, int x, int rt = 1){
            if(L>=r[rt] or l[rt]>=R) return;
            if(L<=l[rt] and r[rt]<=R){
                lazy[rt] = minn[rt] = x;
                return;
            }
            pushdown(rt);
            modify(L,R,x,ls(rt)); modify(L,R,x,rs(rt));
            pushup(rt);
        }
        int query(int L, int R, int rt = 1){
            if(L>=r[rt] or l[rt]>=R) return INF;
            if(L<=l[rt] and r[rt]<=R) return minn[rt];
            pushdown(rt);
            return min(query(L,R,ls(rt)),query(L,R,rs(rt)));
        }
    }ST;
    
    void solve(){
        ____();
        cin >> n >> k;
        for(int i = 0; i < n; i++) cin >> A[i][0], A[i+n][0] = A[i][0];
        for(int j = 1; (1 << j) <= (n << 1); j++) for(int i = 0; i + (1 << j) - 1 < (n << 1); i++) A[i][j] = min(A[i][j-1],A[i+(1<<(j-1))][j-1]);
        auto query = [&](int l, int r){
            int d = (int)log2(r - l + 1);
            return min(A[l][d],A[r-(1<<d)+1][d]);
        };
        int q; cin >> q;
        vector<int> vec;
        for(int i = 0; i < q; i++){
            cin >> Q[i].type >> Q[i].l >> Q[i].r;
            Q[i].l--; Q[i].r--;
            if(Q[i].type==1) cin >> Q[i].x;
            vec.push_back(Q[i].l); vec.push_back(Q[i].r);
        }
        sort(vec.begin(),vec.end());
        vec.erase(unique(vec.begin(),vec.end()),vec.end());
        vector<pair<int,int> > vcc;
        for(int i = 1, lim = vec.size(); i < lim; i++){
            if(vec[i]==vec[i-1]+1) continue;
            if(vec[i]-vec[i-1]+1>=n) vcc.push_back({vec[i-1]+1,query(0,n-1)});
            else{
                int l = vec[i-1] % n, r = vec[i] % n;
                if(l>r) r += n;
                vcc.push_back({vec[i-1]+1,query(l+1,r-1)});
            }
        }
        for(int i = 0; i < (int) vec.size(); i++) vcc.push_back({vec[i],A[vec[i]%n][0]});
        sort(vcc.begin(),vcc.end());
        ST.build(0,vcc.size(),vcc);
        for(int i = 0; i < q; i++){
            int l = Q[i].l, r = Q[i].r;
            l = lower_bound(vcc.begin(),vcc.end(),make_pair(l,0)) - vcc.begin();
            r = lower_bound(vcc.begin(),vcc.end(),make_pair(r,0)) - vcc.begin();
            if(Q[i].type==1) ST.modify(l,r+1,Q[i].x);
            else printf("%d
    ",ST.query(l,r+1));
        }
    }
    int main(){
        #ifndef ONLINE_JUDGE
        freopen("Local.in","r",stdin);
        freopen("ans.out","w",stdout);
        #endif
        solve();
        return 0;
    }
    
  • 相关阅读:
    九校联考-DL24凉心模拟Day2T2 整除(division)
    九校联考-DL24凉心模拟Day1T3 三米诺 (tromino)
    九校联考-DL24凉心模拟总结
    异常 日志-<多重catch语句>
    时间和日期实例-<Calender计算出生日期相差几天>
    时间和日期-<Date和SimpleDateFormat>
    实用类-<Math类常用>
    实用类-<字符串与基本类型的转换>
    实用类-<装箱与拆箱>
    HashMap的应用
  • 原文地址:https://www.cnblogs.com/kikokiko/p/13519252.html
Copyright © 2020-2023  润新知