11.1-11.3
什么都没干。
11.4
HNU 10104 病毒
又是卡了很久的题目。其实已经改出了可以AC的代码。但是不能理解差别。
后来试了一种可以理解的简单做法发现能过就先这样吧- -。
题意:给n个二进制串,问能否构造出不包含这n个串的无限长二进制串。
最后的做法是简单的丢到AC自动机里。然后dfs找一个没有单词结尾的环。
没有单词结尾是这个节点和它顺着fail到root的路上都没有单词结尾。

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 using namespace std; 7 const int maxnode=3e4+10,sigma_size=2; 8 const int maxn=3e4+10; 9 int n,p[maxn]; 10 char s[maxnode]; 11 12 struct Ac_auto 13 { 14 int Next[maxnode][sigma_size]; 15 int fail[maxnode]; 16 int val[maxnode]; 17 int vis[maxnode]; 18 int sz; 19 Ac_auto(){sz=1;memset(Next[0],0,sizeof(Next[0]));} 20 void init() 21 { 22 vis[0]=val[0]=0; 23 sz=1;memset(Next[0],0,sizeof(Next[0])); 24 } 25 int idx(char c) {return c-'0';} 26 27 void insert(char *s) 28 { 29 int u=0,n=strlen(s); 30 for(int i=0;i<n;i++) 31 { 32 int c=idx(s[i]); 33 if(!Next[u][c]) 34 { 35 memset(Next[sz],0,sizeof(Next[sz])); 36 val[sz]=vis[sz]=0; 37 Next[u][c]=sz++; 38 } 39 u=Next[u][c]; 40 } 41 val[u]=1; 42 } 43 44 void build() 45 { 46 queue<int> q; 47 fail[0]=0; 48 for(int i=0;i<sigma_size;i++) if(Next[0][i]) 49 { 50 fail[Next[0][i]]=0; 51 q.push(Next[0][i]); 52 } 53 while(!q.empty()) 54 { 55 int pos=q.front(); q.pop(); 56 for(int i=0;i<sigma_size;i++) 57 { 58 if(!Next[pos][i]) Next[pos][i]=Next[fail[pos]][i]; 59 else 60 { 61 fail[Next[pos][i]]=Next[fail[pos]][i]; 62 q.push(Next[pos][i]); 63 } 64 } 65 } 66 } 67 68 bool dfs(int pos) 69 { 70 vis[pos]=1; 71 for(int i=0;i<sigma_size;i++) 72 { 73 int u=Next[pos][i],flag=0; 74 while(u) 75 { 76 if(val[u]) {flag=1; break;} 77 u=fail[u]; 78 } 79 if(flag) continue; 80 if(vis[Next[pos][i]]||dfs(Next[pos][i])) return true; 81 } 82 vis[pos]=0; 83 return false; 84 } 85 86 }ACA; 87 88 int main(void) 89 { 90 while(~scanf("%d",&n)) 91 { 92 ACA.init(); 93 for(int i=1;i<=n;i++) 94 { 95 scanf("%s",s+p[i-1]); 96 ACA.insert(s+p[i-1]); 97 p[i]=p[i-1]+strlen(s+p[i-1]); 98 } 99 ACA.build(); 100 puts(ACA.dfs(0)?"TAK":"NIE"); 101 } 102 return 0; 103 }
11.5
补BC。
HDU 5524 Subtrees
我的做法是把子树分成满二叉树和非满二叉树两种统计。
深度记为dep。如果本身就是满。那么满二叉子树有dep种。
如果自身不是满。那么左右子树必有一颗满。
左满有dep-2种。右满有dep-1种。
再统计非满的二叉子树个数。
只要找到最小的非满二叉子树。那么所有包含这棵树的都是。

1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 typedef long long LL; 5 LL pow[61]; 6 7 int main(void) 8 { 9 pow[0]=1LL; 10 for(int i=1;i<61;i++) pow[i]=pow[i-1]*2LL; 11 LL N; 12 while(~scanf("%I64d",&N)) 13 { 14 int ans,dep=1,cnt=0; 15 while(N>pow[dep]-1LL) dep++; 16 LL t=N-pow[dep-1]+1; 17 if(t==pow[dep-1]) ans=2*dep-1; 18 else if(t<pow[dep-2]) ans=2*dep-3; 19 else ans=2*dep-2; 20 while(t%2LL==0) ans--,t/=2LL; 21 printf("%d ",ans); 22 } 23 return 0; 24 }
HDU 5525 Product

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 const LL MOD=1e9+7; 8 const int maxn=1e5; 9 LL pr[maxn],cnt[maxn]; 10 int pos[maxn]; 11 12 void GetPrime() 13 { 14 memset(pr,0,sizeof(pr)); 15 for(int i=2;i<=maxn;i++) 16 { 17 if(!pr[i]) pr[++pr[0]]=i; 18 for(int j=1;j<=pr[0]&&pr[j]*i<=maxn;j++) 19 { 20 pr[i*pr[j]]=1; 21 if(i%pr[j]==0) break; 22 } 23 } 24 for(int i=1;i<=pr[0];i++) pos[pr[i]]=i; 25 return; 26 } 27 28 LL qpow(LL a,LL b) 29 { 30 LL d=1,t=a; 31 while(b) 32 { 33 if(b%2) d=(d*t)%MOD; 34 b/=2; 35 t=(t*t)%MOD; 36 } 37 return d; 38 } 39 40 int main(void) 41 { 42 GetPrime(); 43 int n; 44 while(~scanf("%d",&n)) 45 { 46 memset(cnt,0,sizeof(cnt)); 47 for(int i=1;i<=n;i++) 48 { 49 LL x; scanf("%I64d",&x); 50 int cur=i; 51 for(int j=1;j<=pr[0];j++) 52 { 53 if(cur<(LL)pr[j]*pr[j]) break; 54 if(cur%pr[j]==0) 55 { 56 LL t=0; 57 while(cur%pr[j]==0) {t++; cur/=pr[j];} 58 cnt[j]=(cnt[j]+x*t)%(2*MOD-2); 59 } 60 } 61 if(cur>1) cnt[pos[cur]]=(cnt[pos[cur]]+x)%(2*MOD-2); 62 } 63 LL Q=1LL,ans=1LL; 64 for(int i=1;i<=pr[0];i++) Q=Q*(cnt[i]+1)%(2*MOD-2); 65 for(int i=1;i<=pr[0];i++) 66 { 67 LL b=(cnt[i]*Q)%(2*MOD-2)/2; 68 ans=ans*qpow(pr[i],b)%MOD; 69 } 70 printf("%I64d ",ans); 71 } 72 return 0; 73 }
HDU 5526 Lie
按照官方题解敲的。(好像并没有多少人去补这题。

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 int num[1010][1010]; 7 int val[1010][1010]; 8 int dp[1010]; 9 10 int main(void) 11 { 12 int N; 13 while(~scanf("%d",&N)) 14 { 15 memset(num,0,sizeof(num)); 16 memset(val,0,sizeof(val)); 17 memset(dp,0,sizeof(dp)); 18 for(int i=1;i<=N;i++) 19 { 20 int A,B; 21 scanf("%d%d",&A,&B); 22 if(A+B+1>N) continue; 23 num[A+B+1][0]++; 24 num[A+B+1][A+1]++; 25 } 26 for(int i=1;i<=N;i++) 27 { 28 for(int j=1;i*j<=N;j++) 29 { 30 int tmp=0; 31 for(int k=1;k<=i*j;k++) tmp+=min(j,num[i][k]); 32 val[i][j]=tmp; 33 } 34 for(int v=N;v>=0;v--) 35 for(int j=1;i*j<=N;j++) 36 if(v>=i*j) dp[v]=max(dp[v],dp[v-i*j]+val[i][j]); 37 } 38 printf("%d ",dp[N]); 39 } 40 return 0; 41 }
补完一套BC。
11.6-11.7
什么都没干。