几道树状数组的模板题

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  } 

 

以上是关于几道树状数组的模板题的主要内容,如果未能解决你的问题,请参考以下文章

树状数组模板题:一本通1535

P3374 模板树状数组 1(单点修改区间查询)(树状数组)

水比的 树状数组 刷题记录

树状数组模板题(特强浓雾

Light bulbs (树状数组模板题)

HDU-1754 I Hate It (树状数组模板题——单点更新,区间查询最大值)