• 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
  • 相关阅读:
    论如何O(1)快速乘
    luogu3605晋升者计数
    分数规划小结
    洛谷 P1589 泥泞路 & 2019青岛市竞赛(贪心)
    洛谷 P3368 【模板】树状数组 2(区间加,单点查询)
    前缀和序列 & 差分序列
    洛谷 P3374 【模板】树状数组 1(单点加,区间和)
    2019青岛市程序设计竞赛游记
    0x3f3f3f3f 0xbfbfbfbf 等的原理及应用
    memset 初始化数组 & 实现原理
  • 原文地址:https://www.cnblogs.com/monmonde/p/3960094.html
Copyright © 2020-2023  润新知