codeforces round428 div 2

来源:互联网 发布:学软件编程 编辑:程序博客网 时间:2024/06/06 01:24

she像我这种垃圾选手只能跑来搞div 2.。。
rating增加的好慢啊,不知道何年何月能上紫。。。

A:暴力傻逼题,开场3分钟切。

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e5+5;int n,m,k;int a[N];int main(){    scanf("%d%d",&n,&k);    fo(i,1,n)scanf("%d",&a[i]);    int sum1=0,sum2=0;    int i;    for(i=1;i<=n;i++)    {        sum1+=a[i];        if (sum1>=8)sum1-=8,sum2+=8;        else sum2+=sum1,sum1=0;        if (sum2>=k)break;    }    if (sum2<k)printf("-1\n");    else    printf("%d\n",i);}

B:比较麻烦的贪心题,想法是,对于一个四连,相当于两个二连。
那么先把四连和二连坐满,然后只剩余3,2,1三种情况,然后3可以坐两个到二连,然后就是1 2了,随便分类讨论一下就好。
但是后来被hack了。。实力掉rating。。
这个是AC的,没被hack

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e5+5;int n,m,k;int a[N];int main(){    scanf("%d%d",&n,&k);    int sum=0;    fo(i,1,k)scanf("%d",&a[i]),sum+=a[i];    int sum1=0,sum2=2*n,sum4=n;    fo(i,1,k)    {        int t=min(sum4,a[i]/4);        a[i]-=t*4;        sum4-=t;    }    sum1+=sum4,sum2+=sum4;    fo(i,1,k)    {        int t=min(sum2,a[i]/2);        a[i]-=t*2;        sum2-=t;    }    sum1+=sum2;    bool flag=1;    fo(i,1,k)    {        int t=min(sum1,a[i]);        a[i]-=t;        sum1-=t;        if (a[i])flag=0;    }    if (!flag)printf("NO\n");    else printf("YES\n");}

C:傻逼期望,dfs一下就好。

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=3e5+5;const double eps=1e-5;int n,m,k;int head[N],go[N],next[N],son[N],tot,vis[N],sum[N];double dp[N];inline void add(int x,int y){    go[++tot]=y;    next[tot]=head[x];    head[x]=tot;}inline void dfs(int x,int fa){    dp[x]=0.0;    int cnt=0;    for(int i=head[x];i;i=next[i])    {        int v=go[i];        if (v!=fa)        {            dfs(v,x);            dp[x]+=dp[v];            cnt++;        }    }    if (cnt)    {        dp[x]/=(double)cnt;        dp[x]+=1.0;    }}int main(){    scanf("%d",&n);    fo(i,1,n-1)    {        int x,y;        scanf("%d%d",&x,&y);        add(x,y);        add(y,x);    }    //dis[1]=0;    dfs(1,1);    printf("%.12lf\n",dp[1]);}

D:枚举每个因子对于所有数的贡献,容斥一下即可

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e6+5;const int mo=1e9+7;typedef long long ll;const double eps=1e-5;int n,m,k;ll a[N],mx,b[N],ans;inline ll mul(ll a,int b){    ll ret=1;    while (b)    {        if (b&1)ret=1ll*ret*a%mo;        a=1ll*a*a%mo;        b>>=1;    }    return ret%mo;}inline void pre(){    scanf("%d",&n);    fo(i,1,n)    {        scanf("%I64d",&a[i]);        mx=max(mx,a[i]);        for(ll j=1;j*j<=a[i];j++)        {            if (a[i]%j==0)            {                b[j]++;                if (j!=a[i]/j)b[a[i]/j]++;            }        }    }}inline void solve(){    fo(i,2,mx)if (b[i])b[i]=(1ll*mul(2,b[i]-1)*b[i])%mo;    fd(i,mx,2)    {        int j=2*i;        while (j<=mx)        {            b[i]=(b[i]-b[j]+mo)%mo;            j+=i;        }        ans=(ans+1ll*b[i]*i)%mo;    }    printf("%I64d\n",ans);}int main(){    ans=0;    pre();    solve();    return 0;}

E:暴力回溯,用Bron-Kerbosch求最大团。
至于为什么。。看tutorial,Claris老爷说他试了一个小时发现团是最优的,所以直接上了。。。
代码就不上了,因为直接贴的模板,cf开源自己找一个看看咯,或者有一个比较好的Bron-Kerbosch算法介绍:
http://www.cnblogs.com/yefeng1627/archive/2013/03/31/2991592.html