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;
}

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;
}

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;
}

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;
}

方法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;
}

时间: 2024-10-17 02:07:56

Codeforces Round #428 (Div. 2)的相关文章

Codeforces Round #428 (Div. 2) D. Winter is here 数学

链接: http://codeforces.com/contest/839/problem/D 题意: 给出一些数,求取出一些数,当他们的GCD大于0时,将数量乘GCD累加到答案上,求累加和. 题解: 这道题比赛的时候忘了考虑重复了,wa掉之后发现可能会出现重复,然而又不会写了.. 这道题需要知道一个公式就是 1*C(n,1)+2*C(n,2)+3*C(n,3)+...+n*C(n,n) = n*2^(n-1) 我们枚举GCD,统计为其倍数的数字数量,先假定其能组成的集合数为贡献, 但是我们发现

Codeforces Round #428 (Div. 2) D. Winter is here[数论 II]

题目:http://codeforces.com/contest/839/problem/D 题意:找出每种情况使得所有数字gcd不为1,对答案的贡献为gcd值乘数字个数. 题解:因为数字不大,可以哈希出每种数字的个数,然后从后往前,f[i]代表在gcd==i时存在的数字搭配种数.每次计算i时,要减去计算过的种数,所以从后向前计算.每个数字贡献次数为${2}^{sum-1}$(写二进制数的情况可以观察出来),所有数字贡献为$sum*{2}^{sum-1}$ 2次x次方可以先预处理取模出来. 1

Codeforces Round #428 (Div. 2) D. Winter is here[数论II][容斥原理]

传送门:http://codeforces.com/contest/839/problem/D Examples input 33 3 1 output 12 input 42 3 4 6 output 39 Note In the first sample the clans are {1},?{2},?{1,?2} so the answer will be 1·3?+?1·3?+?2·3?=?12 题解:当有n个数为x的倍数时 gcd为x对答案的贡献为$1*C_n^1+2*C_n^2+..

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

A. Arya and Bran 水题 #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <iomanip> #include <math.h> #include <map> using namespace

【容斥原理】Codeforces Round #428 (Div. 2) D. Winter is here

给你一个序列,让你对于所有gcd不为1的子序列,计算它们的gcd*其元素个数之和. 设sum(i)为i的倍数的数的个数,可以通过容斥算出来. 具体看这个吧:http://blog.csdn.net/jaihk662/article/details/77161436. 注意1*C(n,1)+2*C(n,2)+...+n*C(n,n)=n*2^(n-1). #include<cstdio> using namespace std; typedef long long ll; #define MOD

(容斥)Codeforces Round #428 (Div. 2) D. Winter is here

D. Winter is here time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Winter is here at the North and the White Walkers are close. John Snow has an army consisting of n soldiers. While the res

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

There are n cities and n?-?1 roads in the Seven Kingdoms, each road connects two cities and we can reach any city from any other by the roads. Theon and Yara Greyjoy are on a horse in the first city, they are starting traveling through the roads. But

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

#include <bits/stdc++.h> using namespace std; int n, k; const int MOD = 1000000007; int a[105], cnt[5]; void solve() { int t; cnt[4]=n,cnt[2]=2*n; for(int i=0;i<k;i++){ t=min(a[i]/4,cnt[4]); a[i]-=4*t; cnt[4]-=t; } cnt[2]+=cnt[4]; cnt[1]+=cnt[4];

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/