几道树状数组的模板题
Posted WA自动机~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了几道树状数组的模板题相关的知识,希望对你有一定的参考价值。
hdu 1166排兵布阵 单点修改+区间查询的树状数组的应用:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define scand(x) scanf("%llf",&x) 12 #define f(i,a,b) for(int i=a;i<=b;i++) 13 #define scan(a) scanf("%d",&a) 14 #define dbg(args) cout<<#args<<":"<<args<<endl; 15 #define pb(i) push_back(i) 16 #define ppb(x) pop_back(x) 17 #define inf 0x3f3f3f3f 18 #define maxn 50005 19 int n,m,t; 20 int c[maxn],a[maxn]; 21 char s[10]; 22 int lowbit(int x) 23 { 24 return x&(-x); 25 } 26 int query1(int x) 27 { 28 int ans=0; 29 for(int i=x;i>0;i-=lowbit(i)) 30 { 31 ans+=c[i]; 32 } 33 return ans; 34 } 35 int query(int l,int r) 36 { 37 return query1(r)-query1(l-1); 38 } 39 int modify(int x,int C) 40 { 41 for(int i=x;i<=n;i+=lowbit(i)) 42 { 43 c[i]+=C; 44 } 45 } 46 int main() 47 { 48 //freopen("input.txt","r",stdin); 49 //freopen("output.txt","w",stdout); 50 std::ios::sync_with_stdio(false); 51 scan(t); 52 f(kk,1,t) 53 { 54 pf("Case %d:\n",kk); 55 mem(c,0); 56 mem(a,0); 57 scan(n); 58 f(i,1,n) 59 { 60 scan(a[i]); 61 modify(i,a[i]); 62 } 63 int x,y; 64 while(scanf("%s",s)) 65 { 66 if(!strcmp(s,"End"))break; 67 scan(x);scan(y); 68 if(s[0]==‘Q‘) 69 { 70 pf("%d\n",query(x,y)); 71 } 72 if(s[0]==‘A‘) 73 { 74 modify(x,y); 75 } 76 if(s[0]==‘S‘) 77 { 78 modify(x,-y); 79 } 80 } 81 } 82 }
hdu1556 单点查询与区间修改的应用:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define scand(x) scanf("%llf",&x) 12 #define f(i,a,b) for(int i=a;i<=b;i++) 13 #define scan(a) scanf("%d",&a) 14 #define dbg(args) cout<<#args<<":"<<args<<endl; 15 #define pb(i) push_back(i) 16 #define ppb(x) pop_back(x) 17 #define inf 0x3f3f3f3f 18 #define maxn 100005 19 int n,m,t; 20 int c[maxn],a[maxn]; 21 int lowbit(int x) 22 { 23 return x&(-x); 24 } 25 void update1(int x,int C) 26 { 27 for(int i=x;i<=n;i+=lowbit(i)) 28 { 29 c[i]+=C; 30 } 31 } 32 void update(int l,int r) 33 { 34 update1(l,1); 35 update1(r+1,-1); 36 } 37 int query(int x) 38 { 39 int res=0; 40 for(int i=x;i>0;i-=lowbit(i)) 41 { 42 res+=c[i]; 43 } 44 return res; 45 } 46 int main() 47 { 48 //freopen("input.txt","r",stdin); 49 //freopen("output.txt","w",stdout); 50 std::ios::sync_with_stdio(false); 51 while(scan(n)==1&&n) 52 { 53 mem(c,0); 54 int l,r; 55 f(kk,1,n) 56 { 57 scan(l); 58 scan(r); 59 update(l,r); 60 } 61 f(i,1,n) 62 { 63 if(i==1)pf("%d",query(i)); 64 else pf(" %d",query(i)); 65 } 66 pf("\n"); 67 } 68 69 }
树状数组中c[i]覆盖从i位置向前的lowbit(i)个位置,所以当用树状数组初始化初值为k的数列时,c[i]=k*lowbit(i);如果是在二维中初始化时c[i][j]=k*lowbit(i)*lowbit(j);
做的时候无限wa,注意初始数组的时候一定注意边界,它的输入是0-1000,所以+1后1-1001区间的数都是要变成1的。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define scand(x) scanf("%llf",&x) 12 #define f(i,a,b) for(int i=a;i<=b;i++) 13 #define scan(a) scanf("%d",&a) 14 #define dbg(args) cout<<#args<<":"<<args<<endl; 15 #define pb(i) push_back(i) 16 #define ppb(x) pop_back(x) 17 #define inf 0x3f3f3f3f 18 #define maxn 1005 19 int n,m,t; 20 int c[maxn][maxn]; 21 int lowbit(int x) 22 { 23 return x&(-x); 24 } 25 26 void update(int x,int y,int C) 27 { 28 for(int i=x;i<maxn;i+=lowbit(i)) 29 { 30 for(int j=y;j<maxn;j+=lowbit(j)) 31 { 32 c[i][j]+=C; 33 } 34 } 35 } 36 int query(int x,int y) 37 { 38 int ans=0; 39 while(x>0) 40 { 41 int tmp=y; 42 while(tmp>0) 43 { 44 ans+=c[x][tmp]; 45 tmp-=lowbit(tmp); 46 } 47 x-=lowbit(x); 48 } 49 return ans; 50 } 51 int query2(int l1,int r1,int l2,int r2) 52 { 53 return query(l2,r2)-query(l1-1,r2)-query(l2,r1-1)+query(l1-1,r1-1); 54 } 55 char s[3]; 56 void aaa() 57 { 58 pf("##################\n"); 59 f(i,1,4) 60 { 61 f(j,1,4) 62 { 63 pf("%d ",query2(i,j,i,j)); 64 } 65 pf("\n"); 66 } 67 pf("##################\n"); 68 } 69 int main() 70 { 71 //freopen("input.txt","r",stdin); 72 //freopen("output.txt","w",stdout); 73 // std::ios::sync_with_stdio(false); 74 scan(t); 75 f(kk,1,t) 76 { 77 mem(c,0); 78 f(i,1,1001)//注意边界 79 f(j,1,1001) 80 { 81 c[i][j]=lowbit(i)*lowbit(j);//设置原数组每一个元素都是1,用update(i,j,1)用O(n*log(n)^2)时间会超时 82 } 83 scan(n); 84 int xa,xb,ya,yb,n1; 85 pf("Case %d:\n",kk); 86 while(n--) 87 { 88 char mm; 89 // getchar(); 90 scanf("%s",&s); 91 if(s[0]==‘S‘) 92 { 93 scanf("%d%d%d%d",&xa,&ya,&xb,&yb); 94 xa++,xb++,ya++,yb++; 95 if(xa>xb)swap(xa,xb); 96 if(ya>yb)swap(ya,yb); 97 pf("%d\n",query2(xa,ya,xb,yb)); 98 } 99 else if(s[0]==‘A‘) 100 { 101 scanf("%d %d %d",&xa,&ya,&n1); 102 update(xa+1,ya+1,n1); 103 } 104 else if(s[0]==‘D‘) 105 { 106 scanf("%d %d %d",&xa,&ya,&n1); 107 xa++,ya++; 108 int tmp=query2(xa,ya,xa,ya); 109 n1=min(n1,tmp); 110 update(xa,ya,-n1); 111 } 112 else if(s[0]==‘M‘) 113 { 114 scanf("%d %d %d %d %d",&xa,&ya,&xb,&yb,&n1); 115 xa++,ya++,xb++,yb++; 116 int tmp=query2(xa,ya,xa,ya); 117 n1=min(n1,tmp); 118 update(xa,ya,-n1); 119 update(xb,yb,n1); 120 } 121 // aaa(); 122 } 123 } 124 }
以上是关于几道树状数组的模板题的主要内容,如果未能解决你的问题,请参考以下文章