• Codeforces Round #697 (Div. 3) ABCDE 题解


    久违的cf服务器爆炸场

    A. Odd Divisor

    思路:任何一个数都可以写成(n = k2^m,其中k是一个奇数),若k=1,那么n就一定是一个2的幂。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #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 pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    int main()
    {
        int kase;
        cin>>kase;
        while(kase--)
        {
            ll n = read();
            int flag = 1;
            for(ll i=1; (1LL<<i)<=n; i++ )
            {
                if((1LL<<i)==n) flag = 0;
            }
            puts(flag?"YES":"NO");
        }
        return 0;
    }
    
    

    B. New Year's Number

    思路:你知道答案肯定是(n = 2020i + 2021j)的形式,那么你只需要枚举i,看j是否存在即可。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #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 pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    int main()
    {
        int kase;
        cin>>kase;
        while(kase--)
        {
            ll n = read();
            int flag = 0;
            for(ll i=0; i*2020<=n; i++)
            {
                ll cur = n - i*2020;
                double num = cur/2021.0;
                if(num==(ll)num)
                {
                    flag = 1;
                    break;
                }
            }
            puts(flag?"YES":"NO");
        }
        return 0;
    }
    

    C. Ball in Berland

    思路:因为只选出两组,我们只需要枚举其中一组的选法,另外一组就自然确定了。枚举a中每个人的舞伴时,当前贡献就是k - 和当前这个a有的舞伴个数 - 要和a跳舞的那个人的舞伴个数 + 本次的1, 画个图自己理解一下就很容易懂了。 最后答案要除2因为会有重复计算的对。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #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 pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 2e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    vector<vector<ll> > a(maxn);
    vector<vector<ll> > b(maxn);
    ll ina[maxn];
    ll inb[maxn];
    
    int main()
    {
        int kase;
        cin>>kase;
        int num = 1;
        while(kase--)
        {
            ll na = read(), nb = read(), k = read();
    
            for(int i=0; i<=na+2; i++)
            a[i].clear();
            for(int i=0; i<=nb+2; i++)
            b[i].clear();
            rep(i,1,k)  ina[i] = read();
            rep(i,1,k)  inb[i] = read();
    
            rep(i,1,k)
            {
                a[ina[i]].pb(inb[i]);
                b[inb[i]].pb(ina[i]);
            }
            ll ans = 0;
            rep(i,1,na)
            {
                for(int j=0; j<a[i].size(); j++)
                {
                    ll cur = a[i][j];
                    ans += k-a[i].size()-b[cur].size()+1;
                }
            }
            cout<<ans/2<<endl;
            num++;
        }
        return 0;
    }
    
    

    D. Cleaning the Phone

    思路:破题口在于b只有两种情况,(bi=1或bi=2),那么我们可以采取前面B题的思路,答案肯定是选了x个bi=1的 + y个bi=2的, 由于贪心策略,我在这两种b的选择中,如果选k个,那肯定选a最大的那k个。 所以就只需要从大到小排序好,记录各自前缀和后,枚举一遍x,用二分看还需要多少个y,然后每次比较取最小即可。

    view code
        #include<iostream>
        #include<string>
        #include<algorithm>
        #include<cstdio>
        #include<cstring>
        #include<cmath>
        #include<map>
        #include <queue>
        #include<sstream>
        #include <stack>
        #include <set>
        #include <bitset>
        #include<vector>
        #define FAST ios::sync_with_stdio(false)
        #define abs(a) ((a)>=0?(a):-(a))
        #define sz(x) ((int)(x).size())
        #define all(x) (x).begin(),(x).end()
        #define mem(a,b) memset(a,b,sizeof(a))
        #define max(a,b) ((a)>(b)?(a):(b))
        #define min(a,b) ((a)<(b)?(a):(b))
        #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 pb push_back
        #define mp make_pair
        #define fi first
        #define se second
        using namespace std;
        typedef long long ll;
        typedef pair<ll,ll> PII;
        const int maxn = 2e5+200;
        const int inf=0x3f3f3f3f;
        const double eps = 1e-7;
        const double pi=acos(-1.0);
        const int mod = 1e9+7;
        inline int lowbit(int x){return x&(-x);}
        ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
        void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
        inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
        inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
        inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
        inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
        int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
        ll a[maxn];
        ll b[maxn];
        ll suma[maxn];
        ll sumb[maxn];
    
        int main()
        {
            int kase;
            cin>>kase;
            while(kase--)
            {
                ll n = read(), m = read();
                rep(i,1,n) a[i] = read();
                rep(i,1,n) b[i] = read();
                vector<ll> one;
                vector<ll> two;
                rep(i,1,n)
                {
                    if(b[i]==1) one.pb(a[i]);
                    else two.pb(a[i]);
                }
                sort(one.begin(),one.end(), greater<ll>());
                sort(two.begin(),two.end(),greater<ll>());
                int lena = one.size();
                int lenb = two.size();
                rep(i,1,lena) suma[i] = suma[i-1] + one[i-1];
                rep(i,1,lenb) sumb[i] = sumb[i-1] + two[i-1];
                ll ans = 1e18;
                rep(i,0,lena)
                {
                    ll One = suma[i];
                    ll need = m - suma[i];
                    if(need<=0)
                    {
                        ans = min(ans,i);
                    }
                    else
                    {
                        int id = lower_bound(sumb+1,sumb+1+lenb, need) - sumb;
                        if(id>lenb) continue;
                        ans = min(ans,id*2+i);
                    }
                }
                if(ans==1e18) cout<<-1<<endl;
                else cout<<ans<<endl;
            }
            return 0;
        }
    
    

    E. Advertising Agency

    水题,预处理一下组合数就行了。我肯定挑的是最大的那k个,每次的贡献就是ans = ans*C(a[i]的个数,要挑出的个数)。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #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 pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    ll dp[1005][1005];
    ll a[maxn];
    
    void init()
    {
        rep(i,0,1003) dp[i][0] = 1;
        rep(i,1,1003) rep(j,1,1003) dp[i][j] = (dp[i-1][j-1] + dp[i-1][j])%mod;
    }
    
    int main()
    {
        init();
        int kase;
        cin>>kase;
        while(kase--)
        {
            map<ll,ll> Map;
            ll n = read(), k =  read();
            rep(i,1,n) a[i] = read(), Map[a[i]]++;
            sort(a+1,a+1+n);
            ll pre = -1;
            ll ans = 1;
            per(i,n,1)
            {
                if(a[i]==pre) continue;
                ll d = min(k,Map[a[i]]);
                ans = ((ans%mod)*(dp[Map[a[i]]][d]%mod))%mod;
                k -= d;
                pre = a[i];
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
    

  • 相关阅读:
    bzoj1854 [Scoi2010]游戏
    bzoj2456 mode
    bzoj4810 [Ynoi2017]由乃的玉米田
    bzoj1076 [SCOI2008]奖励关
    bzoj3064 Tyvj 1518 CPU监控
    bzoj1798 [Ahoi2009]维护序列
    bzoj3575 [Hnoi2014]道路堵塞
    bzoj3992 [SDOI2015]序列统计
    uoj#34. 多项式乘法
    高等代数典型问题集
  • 原文地址:https://www.cnblogs.com/Bgwithcode/p/14329357.html
Copyright © 2020-2023  润新知