• Codeforces Round #697 (Div. 3)题解报告(A-G)


    考完雅思了开始康复训练...争取以后每把都打不咕。

    A.Odd Divisor

    Editorial:偶数有个特性就是可以一直除2,所以我们只需要判断无限除2之后的奇数是不是1即可。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            ll n;scanf("%lld",&n);
            if(n%3==0){puts("YES");continue;}
            while(n%2==0){
                n/=2;
            }
            if(n==1){puts("NO");continue;}
            if(n%2==1){
                puts("YES");
            }else{
                puts("NO");
            }
        }
    }
    View Code

    B. New Year's Number

    Editorial:先尽可能把2020减去,最后会发现一些多余的数,这个时候对多余的数特判,看是否多余2020的组数即可。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n;scanf("%d",&n);
            int d=n/2020;
            int re=n-d*2020;
            if(re>d) puts("NO");
            else puts("YES");
        }
    }
    View Code

    C. Ball in Berland

    Editorial:这个题刚拿到手我就想二分图做法(划掉),但是发现好像不太容易维护边与边之间的关系所以叉掉。 于是正确做法是统计a和b每个人在预配对中的数量,然后O(n)扫一遍枚举统计,因为不可能出现2组a和b都是同一个人的情况,所以mp[a]就代表和a挂钩的人,同理mp[b]代表和b挂钩的人,这时候要处理的时候记得+1,因为a和b自己有搭班。所以最后的时候就把这些结果加起来就ok啦。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int a[maxn],b[maxn];
    map<int,int> mp1,mp2; 
    int main(){
        IO;
        int T;scanf("%d",&T);
        while(T--){
            int x,y,n;scanf("%d%d%d",&x,&y,&n);
            rep(i,1,n) scanf("%d",&a[i]),mp1[a[i]]+=1;
            rep(i,1,n) scanf("%d",&b[i]),mp2[b[i]]+=1;
            ll ans=0;
            rep(i,1,n){
                ans+=(n-mp1[a[i]]-mp2[b[i]]+1);
            }
            cout<<ans/2<<endl;
            mp1.clear();mp2.clear();        
        }
    }
    View Code

    D. Cleaning the Phone

    Editorial:这个题比赛的时候没写出来qwq想着用背包去做但是背包背不下那么大的数据所以肯定得用贪心啦。做法就是对价格为1和2的分别从大到小排序之后分别预处理,以价值2的为例,肯定越往前单个体积越大,所以在每一次处理的时候二分寻找适合的最低的a就行(双指针也可以,因为方向是恒定的),还有记得开ll,扫的时候要从0开始扫

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int a[maxn],b[maxn];
    ll pre1[maxn],pre2[maxn];
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n,m;ll tot=0;scanf("%d%d",&n,&m);
            rep(i,1,n) scanf("%d",&a[i]),tot+=a[i];
            rep(i,1,n) scanf("%d",&b[i]);
            if(tot<m){puts("-1");continue;}
            vector<int> vec1,vec2;
            rep(i,1,n){
                if(b[i]==1) vec1.pb(a[i]);
                else vec2.pb(a[i]);
            }
            sort(vec1.rbegin(),vec1.rend());
            sort(vec2.rbegin(),vec2.rend());
            int cnt1=0,cnt2=0;
            for(auto it:vec1){
                pre1[++cnt1]=pre1[cnt1-1]+it;
            }
            for(auto it:vec2){
                pre2[++cnt2]=pre2[cnt2-1]+it;
            }
            ll ans=inf;
            for(int i=0;i<=cnt2;i++){
                int remain=m-pre2[i];
                ll pos=lower_bound(pre1,pre1+cnt1+1,remain)-pre1;
                if(pre2[i]+pre1[pos]>=m) ans=min(ans,2*i+pos);
            }
            printf("%lld
    ",ans);
            rep(i,1,n) pre1[i]=0,pre2[i]=0;
        }
    }
    View Code

    E. Advertising Agency

    Editorial:读完题就看出很裸的卢卡斯板子题,感觉没什么好讲的。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int a[maxn];map<int,int> mp,vis;
    bool cmp(int a,int b){
        return a>b;
    }
    ll mulit(ll a,ll b,ll m){
        ll ans=0;
        while(b){
            if(b&1) ans=(ans+a)%m;
            a=(a<<1)%m;
            b>>=1;
        }
        return ans;
    }
    
    ll quick_mod(ll a,ll b,ll m){
        ll ans=1;
        while(b){
            if(b&1){
                ans=mulit(ans,a,m);
            }
            a=mulit(a,a,m);
            b>>=1;
        }
        return ans;
    }
    
    ll comp(ll a,ll b,ll m){
        if(a<b) return 0;
        if(a==b) return 1;
        if(b>a-b) b=a-b;
        ll ans=1,ca=1,cb=1;
        for(int i=0;i<b;i++){
            ca=ca*(a-i)%m;
            cb=cb*(b-i)%m;
        }
        ans=ca*quick_mod(cb,m-2,m)%m;
        return ans;
    }
    
    ll lucas(ll a,ll b,ll m){
        ll ans=1;
        while(a&&b){
            ans=(ans*comp(a%m,b%m,m))%m;
            a/=m;
            b/=m;
        }
        return ans;
    }
    
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n,k;scanf("%d%d",&n,&k);
            set<int> s;map<int,int>cnt;
            rep(i,1,n) scanf("%d",&a[i]),mp[a[i]]+=1;
            sort(a+1,a+n+1,cmp);
            rep(i,1,k){
                s.insert(a[i]);
                cnt[a[i]]+=1;
            }
            ll ans=1;
            for(auto it:s){
                ans*=lucas(mp[it],cnt[it],mod);
            }
            cout<<ans<<endl;
            mp.clear();vis.clear();
        }
    }
    View Code

    F.Unusual Matrix

    Editorial:感觉是这套div3里思维含量最大的题了。其实仔细想想,a[i][j]的变动可能会对a[1][j]或者a[i][1]造成影响,但是呢有些时候又可以通过a[1][1]变回来。这里我要介绍一种我自己想的最简单容易理解的方法。首先我们先直接把a[i][j]和b[i][j]取XOR操作,得到c[i][j],这里我要提的一点是a要变成b,必须借c之手。所以我们现在要想的是怎么把c[i][j]变成0,那其实很简单,只需要维护刚刚我说的4个点。把他单独领出来会发现这4个点中如果有奇数个c[i][j]那肯定无法转化。所以只需要特判单偶性就行。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e3+5;
    int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn];
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n;scanf("%d",&n);
            rep(i,1,n) rep(j,1,n) scanf("%1d",&a[i][j]);
            rep(i,1,n) rep(j,1,n) scanf("%1d",&b[i][j]);
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    c[i][j]=a[i][j]^b[i][j];
                }
            }
            bool flag=true;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if((c[i][j]+c[1][1]+c[1][j]+c[i][1])%2==1){
                        flag=false;
                        goto end;
                    }
                }
            } 
            end:;
            if(flag) puts("YES");
            else puts("NO");
        }
    }
    View Code

    G.Strange Beauty

    Editorial:考察的是对素数筛的理解。这里我用的是埃式筛,复杂度O(nlogn),只需要统计每个数他往下有几个可行的数,然后维护最大ans,最后输出n-ans即可

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n;scanf("%d",&n);
            vector<int> cnt(maxn),dp(maxn);
            rep(i,1,n){
                int x;scanf("%d",&x);
                cnt[x]+=1;
            }         
            int ans=0;
            rep(i,1,2e5){
                dp[i]+=cnt[i];
                for(int j=2*i;j<=2e5;j+=i){
                    dp[j]=max(dp[j],dp[i]);
                }
                ans=max(ans,dp[i]);
            }
            cout<<n-ans<<endl;
        }
    }
    View Code
    Codeforces ID:Anonytt QQ: 847399102 可以添加&关注
  • 相关阅读:
    【LeetCode】Validate Binary Search Tree
    【LeetCode】Search in Rotated Sorted Array II(转)
    【LeetCode】Search in Rotated Sorted Array
    【LeetCode】Set Matrix Zeroes
    【LeetCode】Sqrt(x) (转载)
    【LeetCode】Integer to Roman
    贪心算法
    【LeetCode】Best Time to Buy and Sell Stock III
    【LeetCode】Best Time to Buy and Sell Stock II
    CentOS 6 上安装 pip、setuptools
  • 原文地址:https://www.cnblogs.com/Anonytt/p/14329656.html
Copyright © 2020-2023  润新知