• 暑假集训test-8-29


    今天瓜成一坨了。

    瓜的说不出话来。

    直接退役算了我。

    T1

    傻逼题,但是我傻逼地敲了一个线段树合并,然后把空间炸了,只剩20分,

    直接dfs维护子树大小,子树中最大最小值即可统计答案。

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #include<map>
    12 #define Formylove return 0
    13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    15 const int N=1000007; 
    16 typedef long long LL;
    17 typedef double db;
    18 using namespace std;
    19 int n,rt,fa[N];
    20 
    21 template<typename T>void read(T &x)  {
    22     char ch=getchar(); x=0; T f=1;
    23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    24     if(ch=='-') f=-1,ch=getchar();
    25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    26 }
    27 
    28 int ecnt,fir[N],nxt[N],to[N];
    29 void add(int u,int v) {
    30     nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
    31 }
    32 
    33 int ans;
    34 int mi[N],mx[N],sgrt[N],sz[N];
    35 void dfs(int x) {
    36     mi[x]=mx[x]=x;
    37     sz[x]=1; 
    38     for(int i=fir[x];i;i=nxt[i]) {
    39         dfs(to[i]);
    40         sz[x]+=sz[to[i]];
    41         mi[x]=min(mi[x],mi[to[i]]);
    42         mx[x]=max(mx[x],mx[to[i]]);
    43     }
    44     if(sz[x]==mx[x]-mi[x]+1) ans++;
    45 }
    46 
    47 #define ANS
    48 int main() {
    49 #ifdef ANS
    50     freopen("A.in","r",stdin);
    51     freopen("A.out","w",stdout);
    52 #endif
    53     read(n);
    54     For(i,2,n) {
    55         int u,v;
    56         read(u); read(v);
    57         fa[v]=u; add(u,v);
    58     }
    59     For(i,1,n) if(!fa[i]) rt=i;
    60     dfs(rt);
    61     printf("%d
    ",ans);
    62     Formylove;
    63 }
    View Code

    T2

    我已经菜到连f[i][j]表示放完前i个数,最后一个放的数是前i个数中第j大的的方案数的dp都想不出来了。。。

    上午一直在瞎yy一个三方的垃圾算法,以为t1t3稳了这题大概要T一些点,结果T1爆空间T3没拍写挂了,这题却tmd水过去了。。大概就是从小的往大的连边,这个图的拓扑序的数目就是答案,发现这个图很特殊,可以区间dp,f[l][r]表示把l~r取完的方案数,组合数转移,写的是记忆化搜索。

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #include<map>
    12 #define Formylove return 0
    13 #define For(i,a,b) for(register int i=(a);i<=(b);i++)
    14 const int N=1007,p=1000000007;
    15 typedef long long LL;
    16 typedef double db;
    17 using namespace std;
    18 char s[N];
    19 int n,a[N];
    20 LL f[N][N],C[N][N];
    21 vector<int>vc[N]; 
    22 
    23 template<typename T>void read(T &x)  {
    24     char ch=getchar(); x=0; T f=1;
    25     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    26     if(ch=='-') f=-1,ch=getchar();
    27     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    28 }
    29 
    30 void pre() {
    31     For(i,1,n) {
    32         For(k,i+1,n-1) if(a[k]!=1&&a[k+1]!=-1) 
    33             vc[i].push_back(k); 
    34     }
    35 }
    36 
    37 LL dfs(int l,int r) {
    38     if(l>=r) return 1;
    39     if(f[l][r]==-1) {
    40         LL rs=0;
    41         
    42         int k=l;
    43         int ltot=k-l,rtot=r-k;
    44         if(a[k+1]!=-1)
    45             rs=(rs+dfs(l,k-1)*dfs(k+1,r)%p*C[ltot+rtot][ltot]%p)%p;
    46         k=r;
    47         ltot=k-l,rtot=r-k;
    48         if(a[k]!=1)
    49             rs=(rs+dfs(l,k-1)*dfs(k+1,r)%p*C[ltot+rtot][ltot]%p)%p;
    50         int up=vc[l].size();
    51         For(j,0,up-1) {
    52             if(vc[l][j]>=r) break;
    53             k=vc[l][j];
    54             ltot=k-l,rtot=r-k;
    55             rs=(rs+dfs(l,k-1)*dfs(k+1,r)%p*C[ltot+rtot][ltot]%p)%p;
    56         }
    57         f[l][r]=rs;
    58     } 
    59     return f[l][r];
    60 }
    61 
    62 #define ANS
    63 int main() {
    64 #ifdef ANS
    65     freopen("B.in","r",stdin);
    66     freopen("B.out","w",stdout);
    67 #endif
    68     scanf("%s",s);
    69     n=strlen(s);
    70     For(i,0,n-1) {
    71         if(s[i]=='D') a[i+2]=-1;
    72         else if(s[i]=='I') a[i+2]=1;
    73         else a[i+2]=0;
    74     }
    75     ++n;
    76     For(i,0,n) C[i][0]=1;
    77     For(i,1,n) For(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%p; 
    78     memset(f,-1,sizeof(f));
    79     pre();
    80     dfs(1,n);
    81     printf("%lld
    ",f[1][n]);
    82     Formylove;
    83 }
    84 /*
    85 IIDD?DD??I
    86 */
    View Code

    T3

    先dp出lcs,f[i][j]表示a的前i个字符和b的前j个字符的lcs.

    再dp答案。g[i][j]表示a的前i个字符中长度为f[i][j]并且在b的前j个字符中出现过子序列个数。

    两种转移

    1、不选a[i],

      如果f[i-1][j]==f[i][j] 

        g[i][j]+=g[i-1][j]

    2、选a[i]

      找到b的前j个字符中最靠后的一个和a[i]相等的字符b[k],

      如果f[i-1][k-1]+1==f[i][j]

        g[i][j]+=g[i-1][k-1];

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #include<map>
    12 #define Formylove return 0
    13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    15 const int N=1007,p=1e9+7;
    16 typedef long long LL;
    17 typedef double db;
    18 using namespace std;
    19 int n,m,f[N][N];
    20 LL g[N][N]; 
    21 char a[N],b[N];
    22 
    23 template<typename T>void read(T &x)  {
    24     char ch=getchar(); x=0; T f=1;
    25     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    26     if(ch=='-') f=-1,ch=getchar();
    27     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    28 }
    29 
    30 #define ANS
    31 int main() {
    32 #ifdef ANS
    33     freopen("C.in","r",stdin);
    34     freopen("C.out","w",stdout);
    35 #endif
    36     scanf("%s",a);
    37     scanf("%s",b);
    38     n=strlen(a); m=strlen(b);
    39     For(i,0,max(n,m)) g[i][0]=g[0][i]=1;
    40     For(i,1,n) For(j,1,m) {
    41         if(a[i-1]==b[j-1]) f[i][j]=f[i-1][j-1]+1;
    42         else f[i][j]=max(f[i-1][j],f[i][j-1]);
    43     }
    44     For(i,0,max(n,m)) g[i][0]=g[0][i]=1;
    45     For(i,1,n) {
    46         int k=0;
    47         For(j,1,m) {
    48             if(a[i-1]==b[j-1]) k=j; 
    49             if(f[i][j]==f[i-1][j]) g[i][j]=g[i-1][j];
    50             if(k&&f[i-1][k-1]+1==f[i][j]) g[i][j]=(g[i][j]+g[i-1][k-1])%p;
    51         }
    52     }
    53     printf("%lld
    ",g[n][m]);
    54     Formylove;
    55 }
    56 /*
    57 ab
    58 aa
    59 */
    View Code
  • 相关阅读:
    Jmeter性能测试--自己看到的博客收集
    python日志logging
    java学习day12--API-File文件流
    java学习day12--API-IO简介--流简介
    java学习day12--API-SimpleDateFormat--BigDecimal/BigInteger类
    java学习day12--API-包装类-Date类
    equals方法和 == 的使用
    java学习day11--API--Object类-String类-StringBuilder类
    构造方法和普通方法的区别
    java中的修饰符总结
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9555106.html
Copyright © 2020-2023  润新知