codeforces 酱游记

  Codeforces Round #263 Div.1:

  B. Appleman and Tree

  题目大意:给一棵树,每个点可能是黑色或白色。求有多少种方案使得这棵树被分成k份,每份有且仅有一个黑点。

  一看就知道是树形dp,可是不会做...题解思路很巧妙,很有借鉴意义。用dp[v][0]表示当前点及与它同一块的点没有黑点,dp[v][1]表示当前点及与它同一块的点有且仅有一个黑点。然后就是dp了。dp时有一个技巧:当前点为白色,而我们要求dp[v][1]时,我们必须只连接一个dp[child[i]][1]。我们可以直接用dp[v][0]来得到这时候的dp[v][1]。这样做既简洁又方便。实在是很神奇!

 1 //7697563     2014-09-07 04:12:28     moxiaomo     B - Appleman and Tree     GNU C++     Accepted     31 ms     8200 KB 
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 typedef long long LL;
 5 const int maxn=100001;
 6 const LL MOD=1000000007;
 7 
 8 int pos,lin[maxn],ta[maxn],sd[maxn];
 9 inline void biu(int s,int t) { ++pos; lin[pos]=ta[s]; ta[s]=pos; sd[pos]=t; }
10 
11 int n;
12 int color[maxn];
13 LL dp[maxn][2];
14 void dfs(int v)
15 {
16     dp[v][color[v]]=1;
17     for (int i=ta[v];i;i=lin[i])
18     {
19         dfs(sd[i]);
20         if (color[v]==1)
21         {
22             //dp[v][0]=0;
23             dp[v][1]=dp[v][1]*(dp[sd[i]][0]+dp[sd[i]][1])%MOD;
24         }
25         else
26         {
27             dp[v][1]=dp[v][1]*(dp[sd[i]][0]+dp[sd[i]][1])%MOD;
28             dp[v][1]=(dp[v][1]+dp[v][0]*dp[sd[i]][1])%MOD;
29             dp[v][0]=dp[v][0]*(dp[sd[i]][0]+dp[sd[i]][1])%MOD;//--
30         }
31     }
32 } 
33 int main()
34 {
35     scanf("%d",&n);
36     for (int i=0,p;i<n-1;i++) scanf("%d",&p),biu(p,i+1);
37     for (int i=0;i<n;i++) scanf("%d",color+i);
38     dfs(0);
39     cout<<dp[0][1]<<endl;
40 }
B. Appleman and Tree

   C. Appleman and a Sheet of Paper

  简单题。细节的地方需要好好想想。

  关于mid那里为什么错还不清楚...

 1 //7698314     2014-09-07 08:34:09     moxiaomo     C - Appleman and a Sheet of Paper     GNU C++     Accepted     62 ms     760 KB
 2 //iostream,bits/stdc++.h等头文件会导致g++编译变慢
 3 #include <cstdio>
 4 using namespace std;
 5 const int maxn=100001;
 6 
 7 int n;
 8 int len[maxn];
 9 int sh[maxn];
10 void modify(int p,int v) { len[p]+=v; for (int i=p;i<=n;i+=i&(-i)) sh[i]+=v; }
11 int sum(int p)
12 {
13     int ret=0;
14     for (int i=p;i;i-=i&(-i)) ret+=sh[i];
15     return ret;
16 }
17 int main()
18 {
19     int q;
20     scanf("%d%d",&n,&q);
21     for (int i=1;i<=n;i++) modify(i,1);
22     for (int d,l=1,r=n,flag=0,p,a,b;q--;)
23     {
24         scanf("%d",&d);
25         if (d==1)
26         {
27             scanf("%d",&p);
28             int gs=r-l+1;
29             //if (flag) p=gs-p;//--
30             /*int mid=(l+r>>1)-l+1;//--
31             if (mid<=p)//
32             {
33                 p=gs-p;
34                 flag=!flag;
35             }*/
36             if (gs<p*2)
37             {
38                 p=gs-p;
39                 flag=!flag;
40             }
41             if (!flag)
42             {
43                 l+=p;
44                 for (int i=1;i<=p;i++) modify(l+i-1,len[l-i]);
45             }
46             else
47             {
48                 r-=p;
49                 for (int i=1;i<=p;i++) modify(r-i+1,len[r+i]);
50             }
51             //cout<<sum(r)-sum(l-1)<<endl;
52             //printf("%d %d %d
",l,r,flag);
53         }
54         else
55         {
56             scanf("%d%d",&a,&b);
57             printf("%d
",!flag?sum(b+l-1)-sum(a+l-1):sum(r-a)-sum(r-b));
58         }
59     }
60 }
C. Appleman and a Sheet of Paper

   

  Codeforces Round #265 Div.1:

  C. Substitutes in Number

  这是道智商题。从后往前做就能出解。要注意的是最后的size会超long long, 有可能会达到10^10000这种级别。所以要用到费马小定理的知识。

  不过...我把这道智商题转换成了模拟题...

  1 //7717006     2014-09-08 05:05:19    moxiaomo     C - Substitutes in Number     GNU C++    Accepted     108 ms     20500 KB
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <iostream>
  6 #define pb push_back
  7 #define mp make_pair
  8 #define fir first
  9 #define sec second
 10 using namespace std;
 11 typedef long long LL;
 12 const int maxn=100001;
 13 const LL MOD=1000000007;
 14 //LL mi[maxn];
 15 
 16 int pos,ta[10],lin[maxn*2],sd[maxn*2],ssd[maxn*2];
 17 void biu(int s,int t,int tt) { ++pos; lin[pos]=ta[s]; ta[s]=pos; sd[pos]=t; ssd[pos]=tt; }
 18 
 19 LL ksm(LL a,LL n,LL p)
 20 {
 21     LL ret=1;
 22     for (a%=p;n;n>>=1)
 23     {
 24         if (n&1) ret=ret*a%p;
 25         a=a*a%p;
 26     }
 27     return ret;
 28 }
 29 
 30 int q;
 31 char s[maxn],ss[maxn];
 32 
 33 vector< pair<char,int> > bye[maxn];
 34 /*bool vis[maxn];
 35 int jl[maxn],po;
 36 void cl(int v,char c,int f)
 37 {
 38     if (vis[v]) return;
 39     vis[v]=1; jl[++po]=v;
 40     for (int i=0;i<bye[v].size();i++)
 41         if (bye[v][i].sec) cl(bye[v][i].sec,c,f);
 42         else if (bye[v][i].fir==c) bye[v][i].sec=f;
 43 }*/
 44 
 45 LL f[maxn],size[maxn];
 46 pair<LL,LL> solve(int v)
 47 {
 48     if (f[v]!=-1) return mp(f[v],size[v]);
 49     f[v]=0;
 50     pair<LL,LL> tp;
 51     for (int i=bye[v].size()-1;~i;i--)
 52     {
 53         if (bye[v][i].sec)
 54         {
 55             tp=solve(bye[v][i].sec);
 56             f[v]=(f[v]+tp.fir*ksm(10ll,size[v],MOD))%MOD;
 57             size[v]=(size[v]+tp.sec);
 58         }
 59         else
 60             f[v]=(f[v]+(bye[v][i].fir-'0')*ksm(10ll,size[v],MOD))%MOD,
 61             size[v]=(size[v]+1);
 62     }
 63     return mp(f[v],size[v]%=(MOD-1));
 64 }
 65 int main()
 66 {
 67     scanf("%s%d",s,&q);
 68     for (int i=0;s[i];i++)
 69         biu(s[i]-'0',0,i),
 70         bye[0].pb(mp(s[i],0));
 71     for (int i=0;i<=q;i++) f[i]=-1;
 72 
 73     for (int len,tt=1;tt<=q;tt++)
 74     {
 75         scanf("%s",ss);
 76         len=strlen(ss);
 77 
 78         for (int i=ta[ss[0]-'0'];i;i=lin[i])
 79             bye[sd[i]][ssd[i]].sec=tt;
 80         ta[ss[0]-'0']=0;
 81 
 82         for (int i=3;i<len;i++)
 83             biu(ss[i]-'0',tt,i-3),
 84             bye[tt].pb(mp(ss[i],0));
 85         /*cl(0,ss[0],tt);
 86         while (po) vis[jl[po--]]=0;*/
 87     }
 88     cout<<solve(0).fir<<endl;//printf("%I64d
",solve(0).fir);
 89     return 0;
 90 }
 91 
 92     /*for (int i=bye[v].size()-1;~i;i--)
 93         if (bye[v][i].sec) solve(bye[v][i].sec);
 94         else
 95             size[v]+=1,
 96             ans=(ans+(bye[v][i].fir-'0')*tp)%MOD,
 97             tp=tp*10%MOD;*/
 98     /*LL tp=1;
 99     for (int i=strlen(s)-1;~i;i--)
100     {
101         ans[s[i]-'0']=(ans[s[i]-'0']+tp)%MOD;
102         tp=tp*10%MOD;
103     }*/
C. Substitutes in Number

相关推荐