3.7
cf 631 d D - Messenger
不懂写


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 typedef long long LL; 9 const int maxn = 2e5+5; 10 int N,M,n,m,lena,lenb; 11 int p[maxn]; 12 char s[maxn],t[maxn]; 13 14 //gan ba die >_</ 15 16 struct node{ 17 char c; 18 LL x; 19 }; 20 21 node a[maxn],b[maxn],c[maxn],d[maxn]; 22 23 void Get_p(){ 24 p[1] = 0; 25 int j = 0; 26 for(int i = 2;i <= lenb;i++){ 27 while(j > 0 && (b[j+1].c != b[i].c || b[j+1].x != b[i].x)) j =p[j]; 28 if(b[j+1].c == b[i].c && b[j+1].x == b[i].x) j++; 29 p[i] = j; 30 } 31 //for(int i = 1;i <= lenb;i++) printf("p[%d] = %d\n",i,p[i]); 32 } 33 34 void KMP(){ 35 Get_p(); 36 int ans = 0; 37 int j = 0; 38 for(int i = 1;i <= lena;i++){ 39 if(j == lenb-1 && b[j+1].c == a[i].c && b[j+1].x <= a[i].x) { 40 j++; 41 } 42 else{ 43 while(j > 0 && (b[j+1].c != a[i].c || b[j+1].x != a[i].x)) j = p[j]; 44 if(j == 0 && b[j+1].c == a[i].c && b[j+1].x <= a[i].x) j++; 45 else if(b[j+1].c == a[i].c && b[j+1].x == a[i].x) j++; 46 } 47 if(j == lenb){ 48 //printf("--- i = %d j = %d ",i,j); 49 if(a[i].x != b[p[j]].x){ 50 j = 0; 51 ans++; 52 i--; 53 } 54 else{ 55 j = p[j]; 56 ans++; 57 } 58 //printf(" i = %d j = %d\n",i,j); 59 } 60 } 61 62 printf("%d\n",ans); 63 } 64 65 void solve(){ 66 int cnt = 0; 67 for(int i = 1;i <= N;){ 68 int j = i; 69 LL tmp = 0; 70 while(j <= N && c[j].c == c[i].c){ 71 tmp += c[j].x; 72 j++; 73 } 74 a[++cnt].c = c[i].c; 75 a[cnt].x = tmp; 76 i = j; 77 } 78 lena = cnt; 79 cnt = 0; 80 for(int i = 1;i <= M;){ 81 int j = i; 82 LL tmp = 0; 83 while(j <= M && d[j].c == d[i].c){ 84 tmp += d[j].x; 85 j++; 86 } 87 b[++cnt].c = d[i].c; 88 b[cnt].x = tmp; 89 i = j; 90 } 91 lenb = cnt; 92 93 //for(int i = 1;i <= lena;i++) printf("%c %d\n",a[i].c,a[i].x); 94 //for(int i = 1;i <= lenb;i++) printf("%c %d\n",b[i].c,b[i].x); 95 96 if(lenb == 1){ 97 LL res = 0LL; 98 for(int i = 1;i <= lena;i++){ 99 if(a[i].x >= b[1].x && a[i].c == b[1].c){ 100 res += 1LL*(a[i].x - b[1].x+1); 101 } 102 } 103 printf("%I64d\n",res); 104 return; 105 } 106 107 KMP(); 108 109 } 110 111 int main(){ 112 while(scanf("%d %d",&N,&M) != EOF){ 113 char ch; 114 for(int i = 1;i <= N;i++){ 115 scanf("%I64d",&c[i].x); 116 scanf("%c",&ch); 117 scanf("%c",&c[i].c); 118 } 119 for(int i = 1;i <= M;i++){ 120 scanf("%I64d",&d[i].x); 121 scanf("%c",&ch); 122 scanf("%c",&d[i].c); 123 } 124 solve(); 125 } 126 return 0; 127 }
cf 632d D - Longest Subsequence
想的是去枚举从 1 到m的每个数作为lcm,可是没有想到用dp....sad
dp[i] 表示以i 为LCM 的有多少个数


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 1e6+5; 8 int n,m; 9 int a[maxn],dp[maxn],c[maxn]; 10 11 void solve(){ 12 memset(dp,0,sizeof(dp)); 13 for(int i = 1;i <= m;i++){ 14 for(int j = i;j <= m;j+=i){ 15 dp[j] += c[i]; 16 } 17 } 18 int l = 0,r = 0; 19 for(int i = 1;i <= m;i++){ 20 if(dp[i] > r){ 21 r = dp[i]; 22 l = i; 23 } 24 } 25 if(r == 0) l = 1; 26 printf("%d %d\n",l,r); 27 if(r == 0) return; 28 for(int i = 1;i <= n;i++){ 29 if(l%a[i] == 0) printf("%d ",i); 30 } 31 printf("\n"); 32 33 } 34 35 int main(){ 36 while(scanf("%d %d",&n,&m) != EOF){ 37 memset(c,0,sizeof(c)); 38 for(int i = 1;i <= n;i++) { 39 scanf("%d",&a[i]); 40 if(a[i] <= m) c[a[i]]++; 41 } 42 solve(); 43 } 44 return 0; 45 }
3.8
去了一个宣讲会......什么技能都没有.....
累成狗><
老哥曰:慢慢找,可以找到明年的这个时候.......5555555555
3.9
cf 651c 651C - Watchmen


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 #include<map> 7 using namespace std; 8 9 typedef long long LL; 10 const int maxn = 2e5+5; 11 int n,l[maxn],r[maxn]; 12 map<int,int> x; 13 map<int,int> y; 14 map<pair<int,int>,int> xy; 15 16 void solve(){ 17 LL lb = 0LL,ub = 0LL,mid = 0LL; 18 LL tmp = 0LL; 19 for(map<int,int>::iterator it = x.begin();it != x.end();++it){ 20 tmp = it->second; 21 //printf("tmp = %I64d\n",tmp); 22 if(tmp <= 1) continue; 23 lb += 1LL*tmp*(tmp-1LL)/2LL; 24 } 25 for(map<int,int>::iterator it = y.begin();it != y.end();++it){ 26 tmp = it->second; 27 //printf("tmp = %I64d\n",tmp); 28 if(tmp <= 1) continue; 29 ub += 1LL*tmp*(tmp-1LL)/2LL; 30 } 31 for(map<pair<int,int>,int>::iterator it = xy.begin();it != xy.end();++it){ 32 tmp = it->second; 33 if(tmp <= 1) continue; 34 mid += 1LL*tmp*(tmp-1LL)/2LL; 35 } 36 LL ans = lb+ub-mid; 37 printf("%I64d\n",ans); 38 } 39 40 int main(){ 41 while(scanf("%d",&n) != EOF){ 42 x.clear(); 43 y.clear(); 44 xy.clear(); 45 for(int i = 1;i <= n;i++){ 46 scanf("%d %d",&l[i],&r[i]); 47 x[l[i]]++;y[r[i]]++; 48 xy[make_pair(l[i],r[i])]++; 49 } 50 solve(); 51 } 52 return 0; 53 }
3.10
cf 651d D - Image Preview
感觉做法很好理解,可是不好写
参考别人的代码,也调了好久,好挫啊><
觉得很难写的地方是,先一直左滑,再向右滑;和先右滑再左滑
而且没有想到去预处理一个数组出来
还有就是无论怎么滑,第一张照片都是不能跳过的


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 5e5+5; 8 char s[maxn],rs[maxn],t[maxn]; 9 int d[maxn],n,m,a,b; 10 int ans; 11 12 int solve(int key){ 13 memset(d,0,sizeof(d)); 14 if(key == 0){ 15 for(int i = 1;i <= n;i++) s[i] = t[i]; 16 } 17 else { 18 s[1] = t[1]; 19 for(int i = 1;i <= n-1;i++) s[i+1] = t[n-i+1]; 20 } 21 //printf("---key = %d s= %s---\n",key,s+1); 22 int L = 0,R = n; 23 d[1] = 1 + (s[1] == 'h'?0:b); 24 //printf("d[1] = %d\n",d[1]); 25 for(int i = 2;i <= n;i++){ 26 d[i] = d[i-1] + a+1 +(s[i] == 'h'?0:b); 27 if(d[i] > m){ 28 R = i-1; 29 break; 30 } 31 // printf("d[%d] = %d\n",i,d[i]); 32 } 33 if(d[1] > m){return 0;} 34 if(R == 1){return 1;} 35 36 ans = R; 37 //printf("R = %d\n",R); 38 L = n; 39 int zz = (R-1)*a; 40 while(R >= 1){ 41 while(zz + d[R] +a+1+(s[L] == 'h'?0:b) <= m && (R+n-L) < n){ 42 zz += a+1+(s[L] == 'h'?0:b); 43 // printf("-- R = %d L = %d\n",R,L); 44 L--; 45 } 46 ans = max(ans,R+n-L); 47 if(ans >= n){return n;} 48 zz -= a; 49 R--; 50 } 51 //printf(">_< ans = %d\n",ans); 52 return ans; 53 } 54 55 int main(){ 56 while(scanf("%d %d %d %d",&n,&a,&b,&m) != EOF){ 57 scanf("%s",t+1); 58 memset(d,0,sizeof(d)); 59 int res = 0; 60 res = max(solve(0),solve(1)); 61 printf("%d\n",res); 62 } 63 return 0; 64 }
3.11
记录下两次面试,自己好水
3.9 面蘑菇街
哈希,排序,快排的复杂度,什么时候退化成O(n^2),set怎么实现的
堆排,怎么把一颗二叉树调成平衡的
3.10 面阿里
讲解一下 dinic ,二分图匹配;Floyed 的k 为什么放最外面
GG.............
3.12
sb 打表没有打完
hdu 5641 King's Phone


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 int n,k; 9 int a[105]; 10 vector<int> g[15][15]; 11 int vis[105]; 12 int cnt[105]; 13 14 void solve(){ 15 if(n < 4 || n > 9){ 16 puts("invalid"); 17 return; 18 } 19 memset(vis,0,sizeof(vis)); 20 21 for(int i = 1;i <= n;i++){ 22 if(a[i] == 0 || a[i] > 9){ 23 puts("invalid"); 24 return; 25 } 26 } 27 memset(cnt,0,sizeof(cnt)); 28 for(int i = 1;i <= n;i++){ 29 cnt[a[i]]++; 30 if(cnt[a[i]] >= 2){ 31 puts("invalid"); 32 return; 33 } 34 } 35 36 for(int i = 1;i <= n-1;i++){ 37 int u = a[i]; 38 int v = a[i+1]; 39 if(g[u][v].size() == 0){ 40 vis[u] = 1; 41 vis[v] = 1; 42 } 43 else{ 44 int z = g[u][v][0]; 45 if(vis[z] == 0){ 46 puts("invalid"); 47 return; 48 } 49 vis[u] = 1; 50 vis[v] = 1; 51 } 52 } 53 puts("valid"); 54 } 55 56 int main(){ 57 int T; 58 g[1][3].push_back(2); 59 g[1][7].push_back(4); 60 g[1][9].push_back(5); 61 g[2][8].push_back(5); 62 g[3][7].push_back(5); 63 g[3][9].push_back(6); 64 g[4][6].push_back(5); 65 g[7][9].push_back(8); 66 67 g[3][1].push_back(2); 68 g[7][1].push_back(4); 69 g[9][1].push_back(5); 70 g[8][2].push_back(5); 71 g[7][3].push_back(5); 72 g[9][3].push_back(6); 73 g[6][4].push_back(5); 74 g[9][7].push_back(8); 75 scanf("%d",&T); 76 while(T--){ 77 scanf("%d",&n); 78 for(int i = 1;i <= n;i++) scanf("%d",&a[i]); 79 solve(); 80 } 81 return 0; 82 }
3.13
hdu 5642 King's Order
比赛的时候一直想容斥
感觉是 dp,容斥,组合数学都做得太少,碰到题目连类型是什么都不知道了
dp[i][j] 表示到前 i 个位置 末尾有 j个是相同的
注意dp[i][1] 可以是任意的dp[i-1][j] 在末尾填上和i-1位不同的都可以


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 const int mod = 1e9+7; 9 LL dp[5005][105]; 10 int n; 11 12 void Pre(){ 13 memset(dp,0,sizeof(dp)); 14 dp[1][1] = 26LL; 15 for(int i = 2;i <= 2000;i++){ 16 dp[i][2] = (dp[i][2]+dp[i-1][1])%mod; 17 dp[i][3] = (dp[i][3]+dp[i-1][2] )%mod; 18 dp[i][1] = (dp[i][1]+(dp[i-1][1]+dp[i-1][2]+dp[i-1][3])*25)%mod; 19 // printf("dp[%d][1] = %I64d dp[%d][2] = %I64d dp[%d][3] = %I64d\n",i,dp[i][1],i,dp[i][2],i,dp[i][3]); 20 } 21 /* for(int i = 1;i <= 10;i++) 22 for(int j = 1;j <= 3;j++) printf("dp[%d][%d] = %I64d\n",i,j,dp[i][j]);*/ 23 } 24 25 int main(){ 26 int T; 27 scanf("%d",&T); 28 Pre(); 29 while(T--){ 30 scanf("%d",&n); 31 LL ans = dp[n][1] + dp[n][2] + dp[n][3]; 32 printf("%I64d\n",ans%mod); 33 34 } 35 return 0; 36 }
hdu 5643 King's Game
约瑟夫环
题解讲得很清楚了
要滚动一下


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 int dp[2][5005]; 8 int n; 9 int ans[5005]; 10 11 void Pre(){ 12 memset(dp,0,sizeof(dp)); 13 int key = 1; 14 for(int i = 1;i <= 5000;i++){ 15 for(int j = 1;j <= 5000;j++){ 16 dp[key][j] = (dp[1-key][j+1]+j)%i; 17 // printf("dp[%d][%d] = %d\n",i,j,dp[i][j]); 18 } 19 ans[i] = dp[key][1]+1; 20 for(int j = 1;j <= 5000;j++) dp[1-key][j] = dp[key][j]; 21 key = !key; 22 } 23 //for(int i = 1;i <= 10;i++) printf("ans[%d] = %d\n",i,ans[i]+1); 24 } 25 26 int main(){ 27 int T; 28 Pre(); 29 scanf("%d",&T); 30 while(T--){ 31 scanf("%d",&n); 32 printf("%d\n",ans[n]); 33 } 34 return 0; 35 }