zoukankan      html  css  js  c++  java
  • 题解#2

    上一篇好像已经够长了。。。新开一篇

    现在做了几道:

                                                                        12

    BZOJ3829: [Poi2014]FarmCraft

    考虑树DP,我们发现子树走的顺序不同最优值也不同。所以需要安排一个顺序,使得该子树中最晚安装好的点最早安装好。
    这就需要国王游戏中考虑相邻节点的类似方法,具体推导可以见claris神犇的题解:

    http://hi.baidu.com/clrs97/item/408d0adb61dc4f5d21e25078

     1 int n,head[maxn],tot,f[maxn],d[maxn],a[maxn];
     2 struct edge{int go,next;}e[2*maxn];
     3 inline void add(int x,int y)
     4 {
     5     e[++tot]=(edge){y,head[x]};head[x]=tot;
     6     e[++tot]=(edge){x,head[y]};head[y]=tot;
     7 }
     8 inline bool cmp(int x,int y){return max(f[x],d[x]+2+f[y])<max(f[y],d[y]+2+f[x]);}
     9 inline void dfs(int x,int fa)
    10 {
    11     for4(i,x)if(y!=fa)dfs(y,x),d[x]+=d[y]+2; 
    12     int m=0,sum=0;
    13     for4(i,x)if(y!=fa)a[++m]=y;
    14     sort(a+1,a+m+1,cmp);
    15     for1(i,m)
    16     {
    17         f[x]=max(f[x],sum+f[a[i]]+1);
    18         sum+=d[a[i]]+2;
    19     }
    20 }
    21 
    22 int main()
    23 
    24 {
    25 
    26     freopen("input.txt","r",stdin);
    27 
    28     freopen("output.txt","w",stdout);
    29 
    30     n=read();
    31     for1(i,n)f[i]=read();
    32     int ans=f[1];
    33     for1(i,n-1)add(read(),read());
    34     dfs(1,0);
    35     ans=max(2*n-2+ans,f[1]);
    36     printf("%d
    ",ans);
    37 
    38     return 0;
    39 
    40 }  
    View Code

    BZOJ2219: 数论之神

    AC了此题有种满满的成就感233

    题解戳这里吧:http://www.cnblogs.com/dyllove98/archive/2013/08/05/3239030.html

    or  http://hi.baidu.com/lydrainbowcat/item/de72f307d9a4b7823c42e281

    我越来越懒了

     1 int pr[maxn];
     2 map<int,int>mp;
     3 inline int gcd(int x,int y){return y?gcd(y,x%y):x;}
     4 inline int power(int x,int y,int p)
     5 {
     6     int t=1;
     7     for(;y;y>>=1,x=(ll)x*x%p)
     8         if(y&1)t=(ll)t*x%p;
     9     return t;
    10 }
    11 inline int gen(int p)
    12 {
    13     int t=p-1,m=0;
    14     for(int i=2;i*i<=t;i++)if(t%i==0)
    15     {
    16         pr[++m]=i;
    17         while(t%i==0)t/=i;
    18     }
    19     if(t>1)pr[++m]=t;
    20     for(int i=2;;i++)
    21     {
    22         bool flag=0;
    23         for1(j,m)if(power(i,(p-1)/pr[j],p)==1){flag=1;break;}
    24         if(!flag)return i;
    25     }
    26 }
    27 inline int bsgs(int a,int b,int p)
    28 {
    29     if(!b)return 0;
    30     int m=ceil(sqrt(p));
    31     mp.clear();
    32     for(int i=0,j=1;i<m;i++,j=(ll)j*a%p)mp[(ll)b*j%p]=i;
    33     a=power(a,m,p);
    34     for(int i=1,j=a;i<=m;i++,j=(ll)j*a%p)
    35         if(mp.find(j)!=mp.end())return i*m-mp[j];
    36     return -1;
    37 }    
    38 inline int solve(int a,int b,int p,int c,int pc)
    39 {
    40     b%=pc;
    41     if(gcd(b,pc)>1)
    42     {
    43         if(b)
    44         {
    45             int t=0;
    46             while(b%p==0)b/=p,pc/=p,t++,c--;
    47             if(t%a)return 0;
    48                 }else return power(p,c-c/a-(int)(c%a>0),inf);//不可写成c-ceil(c/a)!!! 
    49     }
    50     b=bsgs(gen(p),b,pc);
    51     pc-=pc/p;
    52     a=gcd(a,pc);
    53     return b%a?0:a;
    54 }
    55 
    56 int main()
    57 
    58 {
    59 
    60     freopen("input.txt","r",stdin);
    61 
    62     freopen("output.txt","w",stdout);
    63 
    64     int T=read();
    65     while(T--)
    66     {
    67         int a=read(),b=read(),p=2*read()+1,ans=1;
    68         for(int i=2;i*i<=p&&ans;i++)if(p%i==0)
    69         {
    70             int j=0,k=1;
    71             while(p%i==0)p/=i,k*=i,j++;
    72             ans*=solve(a,b,i,j,k);
    73         }
    74         if(ans&&p>1)ans*=solve(a,b,p,1,p);
    75         printf("%d
    ",ans);
    76     }
    77 
    78     return 0;
    79 
    80 }  
    View Code

    BZOJ3157: 国王奇遇记

    3种做法:

    1)构造矩阵快速幂m^3logn

    2)类似快速幂m^2logn

    前两种做法见:http://wenku.baidu.com/link?url=oUU_lq_wYM37N9QmycWeYXANcoRTT9CcXdTZ8yXznmCMM0meuLF-mmhtq20qQ2hyND9ojWcfLm9ytHK2uS05aj1ICMXnU2giKqGYPgfU7Vm

    3)直接构造 m^2递推

    见:http://blog.miskcoo.com/2014/06/bzoj-3157(ps:貌似有错 是+号而不是-)

    每种做法都没想到T_T

    3最好写所以写了3

     1 int n,m,f[maxn],c[maxn][maxn];
     2 inline int power(int x,int y)
     3 {
     4     int t=1;
     5     for(;y;y>>=1,x=(ll)x*x%mod)
     6         if(y&1)t=(ll)t*x%mod;
     7     return t;
     8 }
     9 
    10 int main()
    11 
    12 {
    13 
    14     freopen("input.txt","r",stdin);
    15 
    16     freopen("output.txt","w",stdout);
    17 
    18     n=read();m=read();
    19     if(m==1){printf("%lld
    ",(ll)n*(n+1)/2%mod);return 0;}
    20     c[0][0]=1;
    21     for1(i,m)
    22     {
    23         c[i][0]=c[i][i]=1;
    24         for1(j,i-1)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    25     }
    26     int inv=power(m-1,mod-2);
    27     f[0]=((ll)(power(m,n+1)-1)*inv-1)%mod;
    28     for1(i,m)
    29     {
    30         int t=0;
    31         for0(j,i-1)t=(t+((ll)((i-j)&1?-1:1)*c[i][j]%mod*f[j]%mod))%mod;
    32         f[i]=((ll)inv*((ll)power(n,i)%mod*power(m,n+1)%mod+t))%mod;
    33     }
    34     printf("%d
    ",(f[m]+mod)%mod);
    35 
    36     return 0;
    37 
    38 }  
    View Code

    这种题以后碰见能想到这么变换?神题

     UPD:矩阵写法 orzzzzzzzzzzzzz  好像这种方法最好想,因为最暴力orzzzzzzzzzz

     1 ll n,m,p;
     2 inline void mul(matrix x,matrix y,matrix z)
     3 {
     4     matrix t;
     5     memset(t,0,sizeof(t));
     6     for0(i,m+1)
     7      for0(j,m+1)
     8       for0(k,m+1)
     9        t[i][j]=(t[i][j]+x[i][k]*y[k][j])%p;
    10     for0(i,m+1)
    11      for0(j,m+1)
    12        z[i][j]=t[i][j];
    13 }
    14 matrix a,b,c;
    15 void ksm(int y)
    16 {
    17     for(;y;y>>=1,mul(a,a,a))
    18         if(y&1)mul(b,a,b);
    19 }
    20 
    21 int main()
    22 
    23 {
    24 
    25     freopen("input.txt","r",stdin);
    26 
    27     freopen("output.txt","w",stdout);
    28 
    29     n=read();m=read();p=read();
    30     c[0][0]=1;
    31     for1(i,m)
    32     {
    33         c[i][0]=c[i][i]=1;
    34         for1(j,i-1)c[i][j]=(c[i-1][j-1]+c[i-1][j])%p;
    35     }
    36     for0(i,m)
    37      for0(j,i)
    38       a[j][i]=m*c[i][j]%p;
    39     a[m][m+1]=a[m+1][m+1]=1;
    40     for0(i,m+1)b[i][i]=1;
    41     ksm(n);
    42     for0(i,m)a[0][i]=m;a[0][m+1]=0;
    43     mul(a,b,a);
    44     cout<<a[0][m+1]<<endl;
    45 
    46     return 0;
    47 
    48 }  
    View Code

     POJ1830开关问题

    解异或方程组比线性的更好写。

    不过不保证有解就得多加一些东西。。。

    直接看代码更容易理解

     1 int n,ans,a[50][50];
     2 inline void gauss()
     3 {
     4     int i,j,k;
     5     for(i=1,j=1;j<=n;i++,j++)
     6     {
     7         for(k=i;!a[k][j]&&k<=n;k++);
     8         if(k>n){i--;continue;}
     9         for2(x,j,n+1)swap(a[i][x],a[k][x]);
    10         for2(x,i+1,n)if(a[x][j])
    11             for2(y,j,n+1)a[x][y]^=a[i][y];
    12     }
    13     for(j=i;j<=n;j++)if(a[j][n+1]){printf("Oh,it's impossible~!!
    ");return;}
    14     printf("%d
    ",1<<(n-i+1));
    15 }
    16 
    17 int main()
    18 
    19 {
    20 
    21     freopen("input.txt","r",stdin);
    22 
    23     freopen("output.txt","w",stdout);
    24     int T=read();
    25     while(T--)
    26     {
    27 
    28       n=read();
    29       memset(a,0,sizeof(a));
    30       for1(i,n)a[i][n+1]=read(),a[i][i]=1;
    31       for1(i,n)a[i][n+1]^=read();
    32       while(1)
    33       {
    34           int x=read(),y=read();
    35           if(!x&&!y)break;
    36           a[y][x]=1;
    37       }
    38       gauss();
    39     }
    40 
    41     return 0;
    42 
    43 }  
    View Code

     BZOJ2466: [中山市选2009]树

    自由元的意思是无论取什么值,都存在一种合法的赋值满足所有方程。

    而哪些非自由元呢?它们的取值是受自由元取值的影响的。

    自由元不确定的话,它们的值也无法知道,因为方程数目不够。

    所以对于此题我们爆搜出所有合法的解,然后取最小个数。

     1 int n,m,tot,ans,a[200][200],b[200];
     2 inline void gauss()
     3 {
     4     for1(i,n)
     5     {
     6         int k=i;
     7         while(k<=n&&!a[k][i])k++;
     8         if(k>n)continue;
     9         for2(j,i,n+1)swap(a[i][j],a[k][j]);
    10         for2(j,i+1,n)if(a[j][i])
    11             for2(k,i,n+1)
    12              a[j][k]^=a[i][k];
    13     }
    14 }
    15 inline void dfs(int x)
    16 {
    17     if(tot>=ans)return;
    18     if(!x){ans=min(ans,tot);return;}
    19     if(a[x][x])
    20     {
    21         b[x]=a[x][n+1];
    22         for2(i,x+1,n)if(a[x][i])b[x]^=b[i];
    23         if(b[x])tot++;
    24         dfs(x-1);
    25         if(b[x])tot--;
    26     }else 
    27     {
    28         b[x]=0;dfs(x-1);
    29         b[x]=1;tot++;dfs(x-1);tot--;
    30     }
    31 }
    32 
    33 int main()
    34 
    35 {
    36 
    37     freopen("input.txt","r",stdin);
    38 
    39     freopen("output.txt","w",stdout);
    40 
    41     while(1)
    42     {
    43         n=read();if(!n)break;
    44         tot=0;ans=inf;
    45         memset(a,0,sizeof(a));
    46         memset(b,0,sizeof(b));
    47         for1(i,n)a[i][i]=1,a[i][n+1]=1;
    48         for1(i,n-1){int x=read(),y=read();a[x][y]=a[y][x]=1;}
    49         gauss();dfs(n);
    50         printf("%d
    ",ans);
    51     }
    52 
    53     return 0;
    54 
    55 }  
    View Code

    BZOJ3866: The Romantic Hero

    简单的背包DP。因为是方案数所以把初值及什么都不取得去掉。用方案的增量来更新答案。

    细节不少。。。

     1 int a[maxn],f[maxn][maxn],g[maxn][maxn];
     2 int main()
     3 {
     4     freopen("input.txt","r",stdin);
     5     freopen("output.txt","w",stdout);
     6     int T=read();
     7     while(T--)
     8     {
     9         int n=read(),ans=0;
    10         for1(i,n)a[i]=read();
    11         memset(g[n+1],0,sizeof(g[n+1]));
    12         g[n+1][1023]=1;
    13         for3(i,n,2)
    14         {
    15          for0(j,1023)g[i][j]=g[i+1][j];
    16          for0(j,1023)g[i][j&a[i]]=(g[i][j&a[i]]+g[i+1][j])%mod;
    17         }
    18         for3(i,n,2)g[i][1023]--;
    19         f[0][0]=1;
    20         for1(i,n-1)
    21         {
    22          for0(j,1023)ans=(ans+(ll)f[i-1][j]*g[i+1][j^a[i]]%mod)%mod;        
    23          for0(j,1023)f[i][j]=(f[i-1][j]+f[i-1][j^a[i]])%mod;
    24         }
    25         printf("%d
    ",ans);
    26     }      
    27     return 0;
    28 }
    View Code

    BZOJ3789: 扫雪车

    有环对答案有没有影响?没环的话肯定直接下界最大流就可以了。

     1 int  n,m,s,t,ss,tt,sum,maxflow,tot=1,head[maxn],cur[maxn],h[maxn];
     2 queue<int>q;
     3 struct edge{int go,next,v;}e[maxm];
     4 void add(int x,int y,int v)
     5 {
     6     e[++tot]=(edge){y,head[x],v};head[x]=tot;
     7     e[++tot]=(edge){x,head[y],0};head[y]=tot;
     8 }
     9 void insert(int x,int y,int l,int r)
    10 {
    11     if(l){add(ss,y,l);add(x,tt,l);}
    12     add(x,y,r-l);
    13 }
    14 bool bfs()
    15 {
    16     for(int i=0;i<=n+1;i++)h[i]=-1;
    17     q.push(s);h[s]=0;
    18     while(!q.empty())
    19     {
    20         int x=q.front();q.pop();
    21         for(int i=head[x];i;i=e[i].next)
    22          if(e[i].v&&h[e[i].go]==-1)
    23          {
    24             h[e[i].go]=h[x]+1;q.push(e[i].go);
    25          }
    26     }
    27     return h[t]!=-1;
    28 }
    29 int dfs(int x,int f)
    30 {
    31     if(x==t) return f;
    32     int tmp,used=0;
    33     for(int i=cur[x];i;i=e[i].next)
    34      if(e[i].v&&h[e[i].go]==h[x]+1)
    35     {
    36         tmp=dfs(e[i].go,min(e[i].v,f-used));
    37         e[i].v-=tmp;if(e[i].v)cur[x]=i;
    38         e[i^1].v+=tmp;used+=tmp;
    39         if(used==f)return f;       
    40     }
    41     if(!used) h[x]=-1;
    42     return used;
    43 }
    44 void dinic()
    45 {
    46     maxflow=0;
    47     while(bfs())
    48     {
    49         for (int i=0;i<=n+1;i++)cur[i]=head[i];maxflow+=dfs(s,inf);
    50     }
    51 }
    52 int main()
    53 {
    54     freopen("input.txt","r",stdin);
    55     freopen("output.txt","w",stdout);
    56     n=read();m=read();s=read();t=read();ss=0;tt=n+1;
    57     while(m--)
    58     {
    59         int x=read(),y=read(),r=read(),l=read();
    60         insert(x,y,l*r,r);
    61         sum+=l*r;
    62     }
    63     insert(t,s,0,inf);
    64     swap(s,ss);swap(t,tt);
    65     dinic();
    66     if(maxflow!=sum){printf("0
    ");return 0;}
    67     swap(s,ss);swap(t,tt);
    68     dinic();
    69     printf("%d
    ",maxflow);
    70     return 0;
    71 }
    View Code

    BZOJ2460: [BeiJing2011]元素

    同CQOINIM游戏

     1 int n,ans;
     2 ll b[maxn];
     3 struct rec{ll x;int y;}a[maxn];
     4 inline bool cmp(rec a,rec b){return a.y>b.y;}
     5 int main()
     6 {
     7     freopen("input.txt","r",stdin);
     8     freopen("output.txt","w",stdout);
     9     n=read();
    10     for1(i,n)a[i].x=read(),a[i].y=read();
    11     sort(a+1,a+n+1,cmp);
    12     for1(i,n)
    13     {
    14         for3(j,63,0)
    15          if(a[i].x>>j&1)
    16           {
    17               if(b[j])a[i].x^=b[j];
    18               else {b[j]=a[i].x;break;}
    19           }
    20         if(a[i].x)ans+=a[i].y;
    21     }
    22     cout<<ans<<endl;
    23     return 0;
    24 }
    View Code

    BZOJ1342: [Baltic2007]Sound静音问题

    单调队列水。。。


     1 int n,m,k,a[maxn],q[2][maxn],l[2],r[2];
     2 
     3 int main()
     4 
     5 {
     6 
     7     freopen("input.txt","r",stdin);
     8 
     9     freopen("output.txt","w",stdout);
    10 
    11     n=read();m=read();k=read();
    12     for1(i,n)a[i]=read();
    13     l[0]=l[1]=1;
    14     bool flag=0;
    15     for1(i,n)
    16     {
    17         while(l[0]<=r[0]&&a[q[0][r[0]]]<a[i])r[0]--;
    18         q[0][++r[0]]=i;
    19         while(l[1]<=r[1]&&a[q[1][r[1]]]>a[i])r[1]--;
    20         q[1][++r[1]]=i;
    21         while(l[0]<r[0]&&i-q[0][l[0]]>=m)l[0]++;
    22         while(l[1]<r[1]&&i-q[1][l[1]]>=m)l[1]++;
    23         if(i>=m&&a[q[0][l[0]]]-a[q[1][l[1]]]<=k)printf("%d
    ",i-m+1),flag=1;
    24     }
    25     if(!flag)printf("NONE
    ");
    26 
    27     return 0;
    28 }
    View Code

    BZOJ 1370: [Baltic2003]Gang团伙

    水并查集,刚开始把朋友的敌人也合并了。。。

     1 int n,m,fa[maxn],ans;
     2 inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
     3 inline void bing(int x,int y)
     4 {
     5     int xx=find(x),yy=find(y);
     6     fa[yy]=xx;
     7 }
     8 
     9 int main()
    10 
    11 {
    12 
    13     freopen("input.txt","r",stdin);
    14 
    15     freopen("output.txt","w",stdout);
    16 
    17     n=read();m=read();
    18     for1(i,n<<1)fa[i]=i;
    19     for1(i,m)
    20     {
    21         char ch=getchar();
    22         while(ch!='F'&&ch!='E')ch=getchar();
    23         int x=read(),y=read();
    24         if(ch=='F')bing(x,y);//bing(x+n,y+n);
    25         else bing(x,y+n),bing(y,x+n);
    26     }
    27     for1(i,n)if(fa[i]==i)ans++;
    28     cout<<ans<<endl;
    29 
    30     return 0;
    31 
    32 } 
    View Code

    BZOJ1316: 树上的询问

    比2599还简单。。。


     1 struct edge{int go,next,w;}e[2*maxn];
     2 int n,m,cnt1,cnt2,tot,sum,rt,b[maxn],a[maxn],f[maxn],g[maxm],d[maxn],head[maxn],s[maxn];
     3 bool v[maxn];
     4 inline void insert(int x,int y,int z)
     5 {
     6     e[++tot]=(edge){y,head[x],z};head[x]=tot;
     7     e[++tot]=(edge){x,head[y],z};head[y]=tot;
     8 }
     9 inline void getrt(int x,int fa)
    10 {
    11     s[x]=1;f[x]=0;
    12     for(int i=head[x],y;i;i=e[i].next)if(!v[y=e[i].go]&&y!=fa)
    13     {
    14         getrt(y,x);
    15         s[x]+=s[y];
    16         f[x]=max(f[x],s[y]);
    17     }
    18     f[x]=max(f[x],sum-f[x]);
    19     if(f[x]<f[rt])rt=x;
    20 }
    21 inline void getdep(int x,int fa,int w)
    22 {
    23     d[++cnt2]=w;
    24     for4(i,x)if(!v[y]&&y!=fa)getdep(y,x,w+e[i].w);
    25 }      
    26 inline void work(int x)
    27 {
    28     v[x]=1;cnt1=0;cnt2=0;
    29     for4(i,x)if(!v[y])
    30     {
    31         getdep(y,x,e[i].w);
    32         for2(j,cnt1+1,cnt2)for1(k,m)if(d[j]<=a[k])b[k]|=g[a[k]-d[j]];
    33         for2(j,cnt1+1,cnt2)if(d[j]<=1000000)g[d[j]]=1;
    34         cnt1=cnt2;
    35     }
    36     for1(i,m)b[i]|=g[a[i]];
    37     for1(i,cnt2)if(d[i]<=1000000)g[d[i]]=0;
    38     for4(i,x)if(!v[y])
    39     {
    40         sum=s[y];rt=0;
    41         getrt(y,x);
    42         work(rt);
    43     }
    44 }
    45 int main()
    46 {
    47     freopen("input.txt","r",stdin);
    48     freopen("output.txt","w",stdout);
    49     n=read();m=read();
    50     for1(i,n-1)
    51     {
    52         int x=read(),y=read(),z=read();insert(x,y,z);
    53     }
    54     for1(i,m)a[i]=read();
    55     g[0]=1;
    56     f[rt=0]=inf;
    57     sum=n;
    58     getrt(1,0);
    59     work(rt);
    60     for1(i,m)printf("%s
    ",b[i]?"Yes":"No");
    61     return 0;
    62   
    63 }  
    View Code

     BZOJ2662: [BeiJing wc2012]冻结

    破水题WA两发。。。

     1 int n,m,k,head[maxn],d[maxn][55],tot;
     2 struct edge{int go,next,w;}e[2*maxm];
     3 queue<pa>q;
     4 bool v[maxn][15];
     5 inline void add(int x,int y,int w)
     6 {
     7     e[++tot]=(edge){y,head[x],w};head[x]=tot;
     8     e[++tot]=(edge){x,head[y],w};head[y]=tot;
     9 }
    10  
    11 int main()
    12  
    13 {
    14     freopen("input.txt","r",stdin);
    15     freopen("output.txt","w",stdout);
    16     n=read();m=read();k=read();
    17     for1(i,m)
    18     {
    19         int x=read(),y=read(),w=read();
    20         add(x,y,w);
    21     }
    22     for1(i,n)for0(j,k)d[i][j]=inf;
    23     d[1][0]=0;
    24     q.push(pa(1,0));
    25     while(!q.empty())
    26     {
    27         int x=q.front().first,z=q.front().second;q.pop();
    28         v[x][z]=0;
    29         for4(i,x)
    30         {
    31             if(d[x][z]+e[i].w<d[y][z])
    32             {
    33                 d[y][z]=d[x][z]+e[i].w;
    34                 if(!v[y][z]){v[y][z]=1;q.push(pa(y,z));}
    35             }
    36             if(d[x][z]+e[i].w/2<d[y][z+1]&&z<k)
    37             {
    38                 d[y][z+1]=d[x][z]+e[i].w/2;
    39                 if(!v[y][z+1]){v[y][z+1]=1;q.push(pa(y,z+1));}
    40             }
    41         }
    42     }
    43     int ans=inf;
    44     for0(i,k)ans=min(ans,d[n][i]);
    45     cout<<ans<<endl;
    46     return 0;
    47 }  
    View Code
  • 相关阅读:
    典型用户模版和场景
    第一冲刺阶段——个人工作总结05
    第一冲刺阶段——个人工作总结04
    第一冲刺阶段——个人工作总结03
    第一冲刺阶段——个人工作总结02
    第一冲刺阶段——个人工作总结01
    学习进度条7
    构建之法阅读笔记06
    个人总结
    第十六周进度条
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4220999.html
Copyright © 2011-2022 走看看