• Codeforces Round #428 (Div. 2)


    Codeforces Round #428 (Div. 2)

    A    看懂题目意思就知道做了

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005;
    
    int n, k, a[110];
    int main()
    {
        scanf("%d%d", &n, &k);
        int cnt=0, sum=0, ans=0;
        rep(i,1,n)
        {
            scanf("%d", &a[i]);
            cnt += a[i];
            sum += min(cnt, 8);
            cnt -= min(cnt, 8);
            if(sum >= k) { ans = i; break; }
        }
        if(ans) printf("%d
    ", ans);
        else puts("-1");
    
        return 0;
    }
    View Code

    B     模拟,有点坑

    tags:统计出 4人座、2人座、1人座  的数量,然后变化即可

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 10005;
    
    int n, k, a[N], b1, b2, b3;
    int main()
    {
        scanf("%d%d", &n, &k);
        rep(i,1,k) scanf("%d", &a[i]);
        b1=n*2, b2=n, b3=0;
        rep(i,1,k) if(a[i]>=4)
        {
            int x=min(b2, a[i]/4);
            b2 -= x,  a[i] -= x*4;
        }
        if(b2) b1+=b2, b3+=b2; 
        rep(i,1,k) if(a[i])
        {
            int x=min(b1, a[i]/2);
            b1 -= x,  a[i] -= x*2;
            x=min(b3, a[i]);
            b3 -= x,  a[i] -= x;
            if(a[i] && b1) --b1, --a[i];
            if(a[i]) {
                return 0*printf("NO
    ");
            }
        }
        puts("YES");
    
        return 0;
    }
    View Code

    C    水 dfs

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005;
    
    int n;
    double ans;
    vector<int > G[N];
    void dfs(int u, int fa, double p, int len)
    {
        if(G[u].size()==1 && u!=1) ans += p*len;
        double p2 = p*1/(G[u].size()-1+(u==1));
        for(auto v : G[u]) if(v!=fa)
        {
            dfs(v, u, p2, len+1);
        }
    }
    int main()
    {
        scanf("%d", &n);
        int u, v;
        rep(i,1,n-1)
        {
            scanf("%d%d", &u, &v);
            G[u].PB(v);  G[v].PB(u);
        }
        dfs(1, 0, 1, 0);
        printf("%.6f
    ", ans);
    
        return 0;
    }
    View Code

    D     容斥、莫比乌斯反演

    tags:

    考虑枚举 gcd, f(d)=∑k 表示gcd为d的所有子集的长度和, 设 F(d)=∑f(n) 要求 d|n  。

    如有cnt个数是d的倍数,易知 F(d)=1*C(cnt,1)+2*(cnt,2)+.....+cnt*C(cnt,cnt) = cnt* ( C(cnt-1,0)+C(cnt-1,1)+.....+C(cnt-1,cnt-1) ) = cnt*2^(cnt-1) 。 所以我们可以轻松地求出F(d) 。

    下面考虑去重的问题:

    方法1:

    根据莫比乌斯反演, f(d) = ∑ u(n/d) F(n) 要求 d|n 。 答案就是 ans += d*f(d) 要求 2<=d<=max 。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 1000005, mod = 1e9+7;
    
    int n, a[N], cnt[N], vis[N];
    ll  fpow(ll a,int b) {
        ll ans=1;  for(; b; a=a*a%mod, b>>=1) if(b&1) ans=ans*a%mod;
        return ans;
    }
    int mu[N];
    void mobius(int mn)
    {
        mu[1] = 1;
        for(int i=1; i<=mn; ++i)
            for(int j=i+i; j<=mn; j+=i)
                mu[j] -= mu[i];
    }
    int main()
    {
        scanf("%d", &n);
        int mx = 0;
        rep(i,1,n) {
            scanf("%d", &a[i]);
            ++vis[a[i]],  mx = max(mx, a[i]);
        }
        rep(i,1,mx) for(int j=i; j<=mx; j+=i)
            cnt[i] += vis[j];
        mobius(mx);
        ll  ans = 0;
        rep(i,2,mx) if(cnt[i])
        {
            ll  tmp = 0;
            for(int j=i; j<=mx; j+=i) if(mu[j/i] && cnt[j])
            {
                ( tmp += (1LL*mu[j/i]*cnt[j]%mod)*fpow(2, cnt[j]-1)%mod ) %= mod;
            }
            ( ans += 1LL*i*tmp%mod ) %= mod;
        }
        printf("%lld
    ", (ans+mod)%mod );
    
        return 0;
    }
    View Code

    方法2:

    先假定 F(d) 就是所有gcd为d的所有子集的长度和,但这里其实多算了gcd为d 的倍数的集合,所以要减去gcd为d的倍数的集合的贡献。

    所以只要反着来枚举即可。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 1000005, mod = 1e9+7;
    
    int n, a[N], cnt[N], vis[N];
    ll  sum[N];
    ll  fpow(ll a,int b) {
        ll ans=1;  for(; b; a=a*a%mod, b>>=1) if(b&1) ans=ans*a%mod;
        return ans;
    }
    int main()
    {
        scanf("%d", &n);
        int mx = 0;
        rep(i,1,n) {
            scanf("%d", &a[i]);
            ++vis[a[i]],  mx = max(mx, a[i]);
        }
        rep(i,1,mx) for(int j=i; j<=mx; j+=i)
            cnt[i] += vis[j];
        ll  ans = 0;
        per(i,mx,2) if(cnt[i])
        {
            ( sum[i] = 1LL*cnt[i]*fpow(2LL, cnt[i]-1)%mod ) %= mod;
            for(int j=2*i; j<=mx; j+=i)
                sum[i] -= sum[j], ( sum[i] += mod ) %= mod;
            ( ans += sum[i]*i%mod ) %= mod;
        }
        printf("%lld
    ", (ans+mod)%mod );
    
        return 0;
    }
    View Code
  • 相关阅读:
    算法题:N皇后-2
    算法题:串联所有单词的子串
    算法题:二叉树的垂序遍历
    算法题:只出现一次的数字 三
    算法题:等价多米诺骨牌对的数量
    算法:判定字符是否唯一
    算法题:字符串相乘
    算法题:字符串的排列
    算法题:单词规律
    算法题:连通网络的操作次数
  • 原文地址:https://www.cnblogs.com/sbfhy/p/7360150.html
Copyright © 2020-2023  润新知