一些簡單的樹狀數組題
阿新 • • 發佈:2018-10-12
lan else char esp %s clas https 組成 長度
題目鏈接:CF961E
大意:給定一列數$a_i$,求滿足下列條件的數對$(x,y)$的數量:$(1)x<y,(2)a_x\geq y,(3)a_y\geq x$
如果只有前兩個條件那就是很簡單的樹狀數組題
但是這樣做是無法滿足第三個條件的
所以我們可以預處理出滿足第三個條件的情況,並將它們壓進vector中
這樣在統計答案時直接將vector中的元素拿出來,在樹狀數組上求和
註意到在此題中$a_i>n$與$a_i=n$是等價的,所以直接將大於n的$a_i$賦為$n$可以避免離散化
#include<iostream> #include<string> #include<string.h> #include<stdio.h> #include<algorithm> #include<vector> #include<queue> #include<map> using namespace std; int tree[200500],n,a[200500]; vector<int> v[200500]; int lowbit(int x) { return x&(-x); } void add(int pos,int val) { int i; for (i=pos;i<=n;i+=lowbit(i)) tree[i]+=val; }int query(int pos) { int i,ans=0; for (i=pos;i>0;i-=lowbit(i)) ans+=tree[i]; return ans; } int main() { scanf("%d",&n); int i; for (i=1;i<=n;i++) { scanf("%d",&a[i]); a[i]=min(a[i],n); v[min(i-1,a[i])].push_back(i); } long longans=0; memset(tree,0,sizeof(tree)); for (i=1;i<=n;i++) { add(a[i],1); int j,len=v[i].size(); for (j=0;j<len;j++) ans+=query(n)-query(v[i][j]-1); } printf("%I64d",ans); return 0; }
題目鏈接:CF827C
大意:給定一個由"A","G","T","C"組成的字符串,有如下兩種操作
? $1\ x \ c$ :將位置為x的字符替換成c
? $2\ l\ r\ e$:給出一個字符串,它的循環節是$e$(即這個字符串為$ee\ldots$),將它與原字符串的子串$[l\ldots r]$進行比較,求出有多少位能夠匹配
本題的關鍵在於$e\leq 10$,所以很多東西要在$e$上做文章
我們可以對每個字符開$10*10$個樹狀數組(記做$[i][j]$),表示當$e$的長度為$j$時這個字符能處在$e$的第$i$位
樹狀數組再開兩維記錄當前的元素是什麽以及在原串中的位置
在查詢時,對每一個字符統計它的貢獻即可
1 #include<iostream> 2 #include<string> 3 #include<string.h> 4 #include<stdio.h> 5 #include<algorithm> 6 #include<vector> 7 #include<queue> 8 #include<map> 9 using namespace std; 10 const int maxn=1e5+10; 11 int tree[11][11][5][maxn],n,q; 12 char a[100500]; 13 map<char,int>mp; 14 15 int lowbit(int x) 16 { 17 return x&(-x); 18 } 19 20 void add(int x,int y,int id,int pos,int val) 21 { 22 int i; 23 for (i=pos;i<=maxn;i+=lowbit(i)) 24 { 25 tree[x][y][id][i]+=val; 26 } 27 } 28 29 int query(int x,int y,int id,int pos) 30 { 31 int i,ans=0; 32 for (i=pos;i>0;i-=lowbit(i)) 33 ans+=tree[x][y][id][i]; 34 return ans; 35 } 36 37 int main() 38 { 39 scanf("%s",a); 40 memset(tree,0,sizeof(tree)); 41 mp[‘A‘]=0;mp[‘T‘]=1;mp[‘G‘]=2;mp[‘C‘]=3; 42 n=strlen(a); 43 scanf("%d",&q); 44 int i,j; 45 for (i=1;i<=n;i++) 46 { 47 for (j=1;j<=10;j++) 48 add(i%j,j,mp[a[i-1]],i,1); 49 } 50 while (q--) 51 { 52 int op; 53 scanf("%d",&op); 54 if (op==1) 55 { 56 int x;char ch; 57 scanf("%d %c",&x,&ch); 58 for (i=1;i<=10;i++) 59 { 60 add(x%i,i,mp[a[x-1]],x,-1); 61 add(x%i,i,mp[ch],x,1); 62 } 63 a[x-1]=ch; 64 } 65 else if (op==2) 66 { 67 int ans=0,x,y;char e[15]; 68 scanf("%d %d %s",&x,&y,e); 69 int len=strlen(e); 70 for (i=0;i<len;i++) 71 { 72 ans+=(query((x+i)%len,len,mp[e[i]],y)-query((x+i)%len,len,mp[e[i]],x-1)); 73 } 74 printf("%d\n",ans); 75 } 76 } 77 return 0; 78 }
一些簡單的樹狀數組題