1. 程式人生 > >暑假集訓test-8-29

暑假集訓test-8-29

printf 合並 bre rep 是我 efi == open span

今天瓜成一坨了。

瓜的說不出話來。

直接退役算了我。

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\n",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\n",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\n",g[n][m]);
54     Formylove;
55 }
56 /*
57 ab
58 aa
59 */
View Code

暑假集訓test-8-29