zoukankan      html  css  js  c++  java
  • Atcoder arc093

    D-Grid Components

    在一个100*100的网格图上染色,问黑格四连通块的个数为A,白格四连通块的个数为B的一种构造方案?(A,B<=500)

    将整个平面分成50*100的两部分,分别以黑白为背景,一块背景算一个连通块,然后在一种背景上用另一种颜色上去点彩,连通块大小为1,无八连通。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int a,b;
     4 int main()
     5 {
     6     scanf("%d%d",&a,&b);
     7     a--;b--;
     8     puts("100 100");
     9     for (int i=1;i<=50;i++)
    10     {
    11         for (int j=1;j<=100;j++)
    12             if (i%2==0&&j%2==0&&a>0) printf("."),a--;
    13           else printf("#"); 
    14        puts("");
    15     }
    16     for (int i=1;i<=50;i++)
    17     {
    18       for (int j=1;j<=100;j++)
    19            if (i%2==0&&j%2==0&&b>0) printf("#"),b--;
    20          else printf("."); 
    21       puts("");
    22     }
    23     return 0;
    24 }
    View Code

    E-Bichrome Spanning Tree

    在一张图上黑白染色,使得所有同时包含有黑白边的最小生成树权值恰好为X。问有多少种染色方法?

    讨论一下嘛,设原树的mst值为sum。若sum>X,答案为0。

    若sum=X,那么设原树所有最小生成树的边集为S,只要其中不全为同色边,一定存在一棵黑白mst,答案为(2^(m-|S|))*(2^|S|-2)。

    若sum<X。那么S中的边一定都是同色边。考虑加入一条异色边,包含这条异色边的mst一定只包含这条异色边。换边求mst法。定义w[i]为在mst上强加i这条边的贡献=该边权-链上最大。当sum+w[i]<X时,必须同色。当sum+w[i]=X时,至少有一条边要和之前的同色块不同色,有z个。当sum+w[i]>X时,随便染色,有t个。答案为(2^t)*((2^z)-1)*2。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1005;
     5 const int mod=1e9+7;
     6 struct node{int u,v,w;}e[N<<1];
     7 struct _node{int to,next,w;}num[N<<1];
     8 int cnt,head[N],n,m,fa[N][13],dep[N],Max[N][13],f[N],tag[N<<1],t1,t2;
     9 ll sum,x;
    10 bool operator < (const node &A,const node &B) {return A.w<B.w;}
    11 int find(int x) {return x==f[x]?x:f[x]=find(f[x]);}
    12 void add(int x,int y,int w)
    13 {num[++cnt].to=y;num[cnt].next=head[x];num[cnt].w=w;head[x]=cnt;}
    14 void mst()
    15 {
    16   sort(e+1,e+m+1);
    17   for (int i=1;i<=n;i++) f[i]=i;
    18   for (int i=1;i<=m;i++) 
    19     if (find(e[i].u)!=find(e[i].v)) 
    20       sum+=e[i].w,f[find(e[i].u)]=find(e[i].v),tag[i]=1,add(e[i].u,e[i].v,e[i].w),add(e[i].v,e[i].u,e[i].w);
    21 }
    22 void dfs(int x)
    23 {
    24   for (int i=head[x];i;i=num[i].next)
    25     if (num[i].to!=fa[x][0])
    26     {
    27       dep[num[i].to]=dep[x]+1;
    28       fa[num[i].to][0]=x;
    29       Max[num[i].to][0]=num[i].w;
    30       dfs(num[i].to);
    31     }
    32 }
    33 void init()
    34 {
    35   for (int j=1;j<=12;j++)
    36     for (int i=1;i<=n;i++)
    37       fa[i][j]=fa[fa[i][j-1]][j-1],Max[i][j]=max(Max[i][j-1],Max[fa[i][j-1]][j-1]);
    38 }
    39 int jump(int x,int y)
    40 {
    41   if (dep[x]<dep[y]) swap(x,y);
    42   int del=dep[x]-dep[y],ans=0;
    43   for (int i=0;i<=12;i++)
    44     if (del&(1<<i)) ans=max(ans,Max[x][i]),x=fa[x][i];
    45   if (x==y) return ans;
    46   for (int i=12;i>=0;i--)
    47     if (fa[x][i]!=fa[y][i]) ans=max(ans,Max[x][i]),ans=max(ans,Max[y][i]),x=fa[x][i],y=fa[y][i];
    48   return max(max(ans,Max[x][0]),Max[y][0]);//一不小心把Max写成fa了!
    49 }
    50 int ksm(int x,int y)
    51 {
    52   int res=1;
    53   for (;y;x=(ll)x*x%mod,y>>=1)
    54     if (y&1) res=(ll)res*x%mod;
    55   return res;
    56 }
    57 int main()
    58 {
    59   scanf("%d%d",&n,&m);
    60   scanf("%lld",&x);
    61   for (int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    62   mst();
    63   if (sum>x) return puts("0"),0;
    64   else{
    65     dfs(1);init();
    66     for (int i=1;i<=m;i++) 
    67       if (!tag[i])
    68       {
    69         int t=jump(e[i].u,e[i].v);
    70         if (e[i].w-t==x-sum) t1++;
    71         else if (e[i].w-t>x-sum) t2++;
    72       }
    73     if (x==sum) printf("%lld
    ",((ll)ksm(2,t2)*(ksm(2,t1+n-1)-2+mod)%mod)%mod);
    74     else printf("%lld
    ",(ll)ksm(2,t2)*(ksm(2,t1)-1+mod)%mod*2%mod);
    75   }
    76   return 0;
    77 }
    View Code

    F-Dark Horse

    一共有2^n个数。每次相邻两个pk。给你一个数组A,如果x=1,y=Ai,那么y赢,否则1赢。其他的都是较小的赢。问最后剩下的数为1的方案数?n<=16。

    固定1在第一个位置,其他情况都是可以转换的,最后*2^n。那么1最后剩下来当且仅当[2,2],[3,4],[5,8],[9,16],...这些区间中的最小值都不是A中元素。

    可以容斥。dp[i][j]表示放进了i个数,j表示有哪几个区间的最小值已经被确定。

    从大到小枚举元素:1.该元素不作为某个区间的最小值,dp[i][j]<-dp[i-1][j]。2.该元素成为k区间的最小值,用比当前元素大的未被使用的元素填满该区间。

    dp[i][j|(1<<k)]<-dp[i][j]*C(Max-a[i]-j,(1<<k)-1)*jc[1<<k].那么dp[n][i]*jc[(1<<n)-i-1]就是至少有popcount(i)个区间最小值为A中元素,容斥。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int mod=1e9+7;
     4 typedef long long ll;
     5 const int N=66666;
     6 int jc[N],inv[N],n,m,ans,Max,num,dp[20][N],a[N];
     7 void up(int &x,int y) {x=((ll)x+y)%mod;}
     8 int calc(int x){int res=0;while (x) x-=(x&(-x)),res++;return res;}
     9 void init()
    10 {  
    11   jc[0]=jc[1]=inv[0]=inv[1]=1;
    12   for (int i=2;i<Max;i++) jc[i]=(ll)jc[i-1]*i%mod,inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
    13   for (int i=2;i<Max;i++) inv[i]=(ll)inv[i]*inv[i-1]%mod;
    14 }
    15 int C(int n,int m)
    16 {
    17   if (n<m) return 0;
    18   return (ll)jc[n]*inv[m]%mod*inv[n-m]%mod;
    19 }
    20 int main()
    21 {
    22   scanf("%d%d",&n,&m);
    23   for (int i=1;i<=m;i++) scanf("%d",&a[m-i+1]);//从大到小
    24   Max=1<<n;init();
    25   dp[0][0]=1;
    26   for (int i=1;i<=m;i++)
    27     for (int j=0;j<Max;j++)
    28     if (dp[i-1][j])
    29     {
    30       up(dp[i][j],dp[i-1][j]);
    31       for (int k=0;k<n;k++)
    32         if (!(j&(1<<k)))
    33           up(dp[i][j|(1<<k)],(ll)C(Max-a[i]-j,(1<<k)-1)*jc[1<<k]%mod*dp[i-1][j]%mod);
    34     }
    35   for (int i=0;i<Max;i++) 
    36   {
    37     num=calc(i);
    38     if (num&1) up(ans,(mod-(ll)dp[m][i]*jc[Max-i-1]%mod)%mod);
    39     else up(ans,(ll)dp[m][i]*jc[Max-i-1]%mod);
    40   }
    41   printf("%lld
    ",(ll)ans*Max%mod);
    42   return 0;
    43 }
    View Code
  • 相关阅读:
    [android]Xutils具体介绍
    2015:WPS笔试-Android开发岗位
    BZOJ1355: [Baltic2009]Radio Transmission
    HDU 1421 搬寝室 (线性dp 贪心预处理)
    【独立开发人员er Cocos2d-x实战 009】Cocos2dx 菜单项CCMenu使用
    Error configuring application listener of
    SVN分支/合并原理及最佳实践
    SVN创建分支/合并分支/切换分支
    如何转载别人的文章
    让div自适应浏览器窗口居中显示
  • 原文地址:https://www.cnblogs.com/Scx117/p/9175030.html
Copyright © 2011-2022 走看看