1. 程式人生 > >Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E DNA Evolution

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E DNA Evolution

一段 har 字符串 n) str end space col span

DNA Evolution

題目讓我們聯想到樹狀數組或者線段樹,但是如果像普通那樣子統計一段的和,空間會爆炸。

所以我們想怎樣可以表示一段區間的字符串。

學習一發大佬的解法。

開一個C[10][10][4][n],就可以啦,第二維表示e的長度,第一維表示i%e的長度,第三維表示顏色,第四維求和了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5+5;
 4 char s[maxn];
 5 map<char,int> mp;
 6 int C[12][12][4][maxn];
7 int n = 0; 8 void add(int a,int b,int c,int d,int x) 9 { 10 while(d<=n) 11 { 12 C[a][b][c][d] += x; 13 d += (d&-d); 14 } 15 } 16 int sum(int a,int b,int c,int d) 17 { 18 int res = 0; 19 while(d>0) 20 { 21 res += C[a][b][c][d]; 22 d -= (d&-d);
23 } 24 return res; 25 } 26 int main() 27 { 28 mp[A] = 0; 29 mp[T] = 1; 30 mp[G] = 2; 31 mp[C] = 3; 32 cin>>(s+1); 33 n = strlen(s+1); 34 //cout<<(s+1)<<endl; 35 int q,l,r; 36 char e[11]; 37 for(int i=1;i<=n;i++) 38 { 39 for
(int j=1;j<=10;j++) 40 { 41 add((i-1)%j,j,mp[s[i]],i,1); 42 } 43 } 44 cin>>q; 45 while(q--) 46 { 47 int mark = 0; 48 cin>>mark; 49 if(mark==1) 50 { 51 cin>>r>>e; 52 for(int j=1;j<=10;j++) 53 { 54 add((r-1)%j,j,mp[s[r]],r,-1); 55 add((r-1)%j,j,mp[e[0]],r,1); 56 } 57 s[r] = e[0]; 58 } 59 else 60 { 61 cin>>l>>r>>e; 62 int res = 0; 63 int elen = strlen(e); 64 for(int i=0;i<elen;i++) 65 { 66 // cout<<sum((l+i-1)%elen,elen,mp[e[i]],r)<<endl; 67 res += (sum((l+i-1)%elen,elen,mp[e[i]],r)-sum((l+i-1)%elen,elen,mp[e[i]],l-1)); 68 } 69 cout<<res<<endl; 70 } 71 } 72 return 0; 73 } 74 /* 75 A 76 11 77 2 1 1 GCA 78 1 1 T 79 2 1 1 AACGACTG 80 2 1 1 GA 81 2 1 1 C 82 1 1 A 83 1 1 G 84 1 1 A 85 1 1 G 86 1 1 G 87 2 1 1 AG 88 */

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E DNA Evolution