Codeforces Round #428 (Div. 2)

Posted 掉血菜鸡煮熟中

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n", 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\n");
        }
    }
    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\n", 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\n", (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\n", (ans+mod)%mod );

    return 0;
}
View Code

 

以上是关于Codeforces Round #428 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces839B[思维] Codeforces Round #428 (Div. 2)

Codeforces Round #428A

Codeforces Round #428 (Div. 2) C-Journey

Codeforces Round #428 B

Codeforces Round #428C

codeforces round #428 div2