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

    A:判断a,b之间是否有倍数关系,没有输出-1。求出a,b之间的倍数cnt,观察该倍数是否为2的幂次,如果不是输出-1。如果2^x == cnt。按照8,4,2的顺序依次把x取完.

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2010
    #define maxn (N + 10)
    #define maxm (N * 2)
    typedef long long ll;
    const ll INF = (1e7);
    int main(){
        int t;scanf("%d",&t);
        while(t--){
            ll a,b;scanf("%lld%lld",&a,&b);
            ll cnt = 0;
            int flag = 0;
            if(a % b == 0){
                cnt = a / b;flag = 1;
            }
            if(b % a == 0){
                cnt = b / a;flag = 1;
            }
            int n2 = 0;
            while(cnt > 1){
                if(cnt % 2 != 0){
                    flag = 0;break;
                }
                cnt /= 2;n2++;
            }
            ll ans = 0;
            if(!flag){
                ans = -1;
            }
            else{
                ans += n2 / 3;n2 %= 3;
                ans += n2 / 2;n2 %= 2;
                ans += n2;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }

    B:对于每一个si,判断二进制位j是否为1,唯一则bits[j]++。容易发现,除了bits[j] * 2 == n的情况,其他情况答案ans在第j位只能取0。所以记录下所有符合bits[j] * 2 == n的位数。然后dfs找到最小答案。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2010
    #define maxn (N + 10)
    #define maxm (N * 2)
    typedef long long ll;
    const ll INF = (1e7);
    int s[maxn];
    int vis[maxn];
    int bits[40];
    int b[maxn],bn;
    int n,ans;
    void dfs(int idx,int cnt){
        if(!idx){
            if(!cnt)return;
            for(int i = 1;i <= n;i++){
                vis[cnt ^ s[i]]--;
            }
            int flag = 1;
            for(int i = 1;i <= n;i++){
                if(vis[s[i]] != 0){
                    flag = 0;break;
                }
            }
            if(flag){
                ans = cnt;
                return;
            }
            for(int i = 1;i <= n;i++){
                vis[s[i]] = 1;
            }
            return;
        }
        dfs(idx - 1,cnt);
        if(ans)return;
        dfs(idx - 1,cnt | (1<<b[idx]));
    }
    int main(){
        int t;scanf("%d",&t);
        while(t--){
            memset(bits,0, sizeof(bits));
            memset(vis,0, sizeof(vis));
            scanf("%d",&n);
            for(int i = 1;i <= n;i++){
                scanf("%d",&s[i]);
                vis[s[i]]++;
                for(int j = 0;j <= 10;j++){
                    if(s[i]&(1<<j)){
                        bits[j]++;
                    }
                }
            }
            ans = 0;
            bn = 0;
            for(int i = 0;i <= 10;i++){
                if(bits[i] * 2 == n){
                    b[++bn] = i;
                }
            }
            dfs(bn,0);
            if(!ans)ans = -1;
            printf("%d
    ",ans);
        }
        return 0;
    }

    C:容易发现1-2^x的和为2^(x+1)-1,所以从高位向低位遍历。例如101010010,当遍历到左边第一个1时,求出1 - 100000000的和,当遍历到第二个1时,求出100000001 - 101000000的和,因为前边的位数异或值为零,所以等价于求1 - 1000000的和。所以每一个为1的位数加上相应的前缀和就行。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2010
    #define maxn (N + 10)
    #define maxm (N * 2)
    typedef long long ll;
    const ll INF = (1e7);
    int s[maxn];
    int vis[maxn];
    int bits[40];
    int b[maxn],bn;
    int n,ans;
    void init(){
        ll ans = 0;
        for(ll i = 1;i <= N;i++){
            ll x = (i^(i - 1));
            for(int j = 0;j < 32;j++){
                if(x & (1<<j))ans++;
            }
            printf("i = %lld ans = %lld
    ",i,ans);
        }
    }
    int main(){
        //init();
        int t;scanf("%d",&t);
        while(t--){
            ll n;scanf("%lld",&n);
            ll ans = 0;
            for(ll i = 61;i >= 0;i--){
                if(n & (1ll<<i)){
                    ans += (1ll<<(i + 1)) - 1;
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    D:容易发现,topic小的blog必须先放,每一个blog的能取tp,只有1-(tp-1)它的邻居都有,且它没有话题为tp的邻居。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 500010
    #define maxn (N + 10)
    #define maxm (N * 2)
    #define pb push_back
    typedef long long ll;
    const ll INF = (1e7);
    struct blogs{
        int tp,id;
    }b[maxn];
    vector<int> vc[maxn];
    int oup[maxn],on;
    int hp[maxn],col[maxn];
    bool cmp(blogs x,blogs y){
        return x.tp < y.tp;
    }
    int main(){
        //init();
        int n,m;scanf("%d%d",&n,&m);
        for(int i = 1;i <= m;i++){
            int u,v;scanf("%d%d",&u,&v);vc[u].pb(v);vc[v].pb(u);
        }
        for(int i = 1;i <= n;i++){
            scanf("%d",&b[i].tp);b[i].id = i;
        }
        sort(b + 1,b + 1 + n,cmp);
        on = 0;
        int flag = 1;
        for(int i = 1;i <= n;i++){
            oup[++on] = b[i].id;int u = b[i].id;
    
            int bn = 0;
            for(auto v:vc[u]){
                if(col[v])hp[++bn] = col[v];
            }
            sort(hp + 1,hp + 1 + bn);
            int cn = (bn > 0);
            for(int j = 1;j < bn;j++){
                if(hp[j] != hp[j + 1])cn++;
            }
            //printf("u = %d cn = %d
    ",u,cn);
            if(b[i].tp == hp[bn]){
                flag = 0;break;
            }
            if(b[i].tp != cn + 1){
                flag = 0;break;
            }
            col[u] = b[i].tp;
        }
        if(on < n)flag = 0;
        if(flag){
            for(int i = 1;i <= n;i++)printf("%d%c",oup[i],(i == n ? '
    ' : ' '));
        }
        else{
            printf("-1
    ");
        }
        return 0;
    }

    E:我们容易发现:这个差值一定是p的倍数。当从大向小遍历时,可以发现p^ki一定是前面差值 (op[i] = 1 或 -1) sum(op[1]*(p^k[1]) + op[2]*(p^k[2])+……+op[i-1]*(p^k[i-1])) 的因子。所以sum>0时直接减去p^ki,sum = 0,加上p^ki。另外p,k都很大,需要判断差值是为(1e9 + 7)的倍数还是为0,方法是取另一个大质数模差值,如果两个都等于0,说明差值为0.

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1000010
    #define maxn (N + 10)
    #define maxm (N * 2)
    #define pb push_back
    typedef long long ll;
    const ll INF = (1e7);
    const ll mod1 = ((1e9) + 7);
    const ll mod2 = ((1e9) + 37);
    ll ki[maxn];
    ll f_pow(ll x,ll p,ll mod){
        ll ans = 1;
        while(p){
            if(p % 2 == 1){
                ans *= x;ans %= mod;
            }
            x *= x;x %= mod;p /= 2;
        }
        return ans;
    }
    int main(){
        int t;scanf("%d",&t);
        while(t--){
            ll n,p;scanf("%lld%lld",&n,&p);
            for(int i = 1;i <= n;i++)scanf("%lld",&ki[i]);
            sort(ki + 1,ki + 1 + n);
            ll ans1 = 0,ans2 = 0;
            for(int i = n;i >= 1;i--){
                if(ans1 == 0 && ans2 == 0){
                    ans1 += f_pow(p,ki[i],mod1);
                    ans2 += f_pow(p,ki[i],mod2);
                }
                else{
                    ans1 -= f_pow(p,ki[i],mod1);ans1 = (ans1 + mod1) % mod1;
                    ans2 -= f_pow(p,ki[i],mod2);ans2 = (ans2 + mod2) % mod2;
                }
            }
            printf("%lld
    ",ans1);
        }
    
        return 0;
    }
  • 相关阅读:
    [那些你所不知道的鬼畜写法]数据结构小探
    索引
    数据类型
    存储引擎
    事务
    视图、触发器、存储过程、自定义函数
    约束
    数据库介绍
    线程基础、线程池
    操作系统基础
  • 原文地址:https://www.cnblogs.com/cleanerhgf/p/13049100.html
Copyright © 2011-2022 走看看