zoukankan      html  css  js  c++  java
  • 《Codeforces Round #757 (Div. 2)》

    A:贪心一下就行

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 998244353;
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int a[105];
    void solve() {
        int n,L,r,k;scanf("%d %d %d %d",&n,&L,&r,&k);
        for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
        sort(a + 1,a + n + 1);
        int ans = 0;
        for(int i = 1;i <= n;++i) {
            if(a[i] >= L && a[i] <= r && k >= a[i]) ans++,k -= a[i];
        }
        printf("%d\n",ans);
    
    }   
    int main() {
        int ca;scanf("%d",&ca);
        while(ca--) {
            solve();
        }
       // system("pause");
        return 0;
    }
    View Code

    B:也是贪心

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 2e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 998244353;
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int a[N],pos[N];
    struct Node{int id,x;}p[N];
    bool cmp(Node a,Node b) {return a.x < b.x;}
    void solve() {
        int n;scanf("%d",&n);
        for(int i = 1;i <= n;++i) scanf("%d",&p[i].x),p[i].id = i;
        sort(p + 1,p + n + 1,cmp);
        int L = -1,r = 1;
        pos[0] = 0;
        LL sum = 0;
        for(int i = n;i >= 1;--i) {
            if(abs(L) <= r) pos[p[i].id] = L,sum += 2LL * p[i].x * abs(L),--L;
            else pos[p[i].id] = r,sum += 2LL * p[i].x * r,r++;
        }
        printf("%lld\n",sum);
        for(int i = 0;i <= n;++i) printf("%d%c",pos[i],i == n ? '\n' : ' ');
    
    }   
    int main() {
        int ca;scanf("%d",&ca);
        while(ca--) {
            solve();
        }
        //system("pause");
        return 0;
    }
    View Code

    C:这题的话其实和构造出来的数组没太大关系,甚至不需要构造就可以算。

    这里离线随便构造了一个数组,然后dp计了一下异或和。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 2e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 1e9 + 7;
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    struct Node{int L,r,w;}p[N];
    vector<pii> vec[N];
    int val[N],bit[30],r[30];
    LL dp[N][30][2];
    void solve() {
        int n,m;scanf("%d %d",&n,&m);
        for(int i = 1;i <= n;++i) {
            vec[i].clear(),val[i] = 0;
            for(int j = 0;j < 30;++j)
                for(int k = 0;k < 2;++k) dp[i][j][k] = 0;
        }
        for(int i = 0;i < 30;++i) r[i] = 0;
        for(int i = 1;i <= m;++i) {
            scanf("%d %d %d",&p[i].L,&p[i].r,&p[i].w);
            vec[p[i].L].push_back(pii{p[i].r,p[i].w});
        }
        for(int i = 1;i <= n;++i) {
            if(vec[i].size() == 0) {
                for(int j = 0;j < 30;++j) {
                    if(r[j] != 0) val[i] |= (1 << j),r[j] = 0;
                }
            }   
            else {
                for(int j = 0;j < 30;++j) bit[j] = 1;
                for(auto v : vec[i]) {
                    for(int j = 0;j < 30;++j) {
                        int g = (v.second >> j) & 1;
                        if(g == 0) bit[j] = 0;
                    }
                }
                for(int j = 0;j < 30;++j) {
                    if(bit[j] == 1) {
                        val[i] |= (1 << j); 
                        r[j] = 0;
                    }
                }
                for(auto v : vec[i]) {
                    for(int j = 0;j < 30;++j) {
                        int g = (v.second >> j) & 1;
                        if(g == 1 && bit[j] == 0) {
                            if(r[j] == 0) r[j] = v.first;
                            else r[j] = min(r[j],v.first);
                        }
                    }
                }
            }
        }
        //for(int i = 1;i <= n;++i) printf("v %d\n",val[i]);
        LL ans = 0;
        for(int i = 1;i <= n;++i) {
            for(int j = 0;j < 30;++j) {
                int g = (val[i] >> j) & 1;
                dp[i][j][g] = ADD(dp[i][j][g],1); 
                for(int k = 0;k < 2;++k) {
                    dp[i][j][k ^ g] = ADD(dp[i][j][k ^ g],dp[i - 1][j][k]); 
                }
                ans = ADD(ans,(1LL << j) * dp[i][j][1] % Mod);
                for(int k = 0;k < 2;++k) dp[i][j][k] = ADD(dp[i][j][k],dp[i - 1][j][k]);
            }
        }
        printf("%lld\n",ans);
    
    }   
    int main() {
        int ca;scanf("%d",&ca);
        while(ca--) {
            solve();
        }
      //  system("pause");
        return 0;
    }
    View Code

    D1:这里预处理的时候塞了个vector,就被卡常数了。

    cnt[i] - 表示i的倍数的个数。

    那么就有dp[j]  = max(dp[j],dp[i] + cnt[j] * (j - i))

    就是说一开始所有i的倍数都当成gcd = i的代价来算,这时候序列尾有cnt[j]个抬升到gcd = j,那么对于单个抬升增加的代价就是(j - i)。

    很显然j的倍数也就是i的倍数。复杂度nlogn

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 1e6 + 5;
    const int M = 5e6 + 5;
    const LL Mod = 1e9 + 7;
    #define INF 1e9
    #define IN_INF 0x3f3f3f
    #define dbg(ax) cout << "now this num is " << ax << endl;
    
    int a[N],cnt[M];//cnt[i] - i的倍数
    LL dp[M];//当前gcd = i的最大值
    void solve() { 
        int n;scanf("%d",&n);    
        for(int i = 1;i <= n;++i) scanf("%d",&a[i]),cnt[a[i]]++;
        for(int i = 1;i < M;++i) 
            for(int j = i + i;j < M;j += i) cnt[i] += cnt[j];
        for(int i = 1;i < M;++i) dp[i] = 1LL * cnt[i] * i;
        LL ans = 0;
        for(int i = 1;i < M;++i) {
            for(int j = i + i;j < M;j += i) {
                dp[j] = max(dp[j],dp[i] + 1LL * cnt[j] * (j - i));
            }
            ans = max(ans,dp[i]);
        }
        printf("%lld\n",ans);
    }   
    int main() {
        solve();
       // system("pause");
        return 0;
    }
    View Code

    D2:只有a的范围增大了。

    我们考虑对D1的代码进行优化。

    对于cnt计数部分,我们用狄利克雷后缀和优化一下即可。

    对于后序的dp计数,很显然有结论dp[j] >= dp[i] {i | j},那么对于中间还可以增加倍数的情况,显然不是最优转移。

    所以我们每次只需要转移一个素数倍即可。复杂度就压到了nloglogn

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 1e6 + 5;
    const int M = 2e7 + 5;
    const LL Mod = 1e9 + 7;
    #define INF 1e9
    #define IN_INF 0x3f3f3f
    #define dbg(ax) cout << "now this num is " << ax << endl;
    
    int a[N],cnt[M];//cnt[i] - i的倍数
    LL dp[M];//当前gcd = i的最大值
    bool vis[M];
    int prime[M],tot = 0;
    void init() {
        for(int i = 2;i < M;++i) {
            if(!vis[i]) prime[++tot] = i;
            for(int j = 1;j <= tot && prime[j] * i < M;++j) {
                vis[prime[j] * i] = 1;
                if(i % prime[j] == 0) continue;
            }
        }
    }
    void solve() { 
        init();
        int n;scanf("%d",&n);    
        for(int i = 1;i <= n;++i) scanf("%d",&a[i]),cnt[a[i]]++;
         for(int i = 1;i <= tot && prime[i] < M;++i) {
            for(int j = (M - 1) / prime[i];j;--j) {
                cnt[j] += cnt[j * prime[i]];
            }
        }
        for(int i = 1;i < M;++i) dp[i] = 1LL * cnt[i] * i;
        LL ans = 0;
        for(int i = 1;i < M;++i) {
            for(int j = 1;j <= tot && prime[j] * i < M;++j) {
                dp[prime[j] * i] = max(dp[prime[j] * i],dp[i] + 1LL * cnt[prime[j] * i] * (prime[j] * i - i));
            }
            ans = max(ans,dp[i]);
        }
        printf("%lld\n",ans);
    }   
    int main() {
        solve();
       // system("pause");
        return 0;
    }
    View Code

    E:这题题意有点奇奇怪怪,解法好像是动态开点的线段树。

  • 相关阅读:
    Vector3函数理解-计算两向量之间的角度
    Android报错Type Error executing aapt: Return code -1
    android中 onResume()方法什么时候执行 ??(转)
    自行实现Kinect 手势Demo踩的坑
    Kinect 2.0 默认姿势的中文意思
    C#限制float有两位小数
    Android View 从左边滑出动画 ,以及从左上,左下,右上,右下放大动画。
    注册谷歌账户时最后一步验证账户输入手机号说此电话号码无法用于进行验证,如何解决?
    Mac使用sonarqube进行代码检测
    Unable to find method 'org.gradle.api.tasks.TaskInputs.file
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15614456.html
Copyright © 2011-2022 走看看