0%

模板:二维树状数组

http://codeforces.com/problemset/problem/707/E 昨天的一场CF 虽然感觉二维树状数组的复杂度显然不科学...但是莫名其妙跑的飞起... 不过二维树状数组的正确性是可以保证的...先留下来当个模板吧...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int n,m,k,q;
struct pp{
int x,y;
ll w;
};
vector<pp> p[2010];
ll a[2010][2010]={};
int add(int x,int y,ll z)
{
int j;while(x<=n){j=y;while(j<=m){a[x][j]+=z;j+=j&(-j);}x+=x&(-x);}return 0;
}
ll sum(int x,int y)
{
ll s,j;s=0;while(x>0){j=y;while(j>0){s+=a[x][j];j-=j&(-j);}x-=x&(-x);}return s;
}
bool v[2010]={};
bool o[2010]={};
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
{
int len;
scanf("%d",&len);
for(int j=1;j<=len;j++)
{
pp u;
scanf("%d%d%I64d",&u.x,&u.y,&u.w);
add(u.x,u.y,u.w);
p[i].push_back(u);
}
}
scanf("%d",&q);
char s[10];
int x1,x2,y1,y2;
int e;
for(int i=1;i<=q;i++)
{
scanf("%s",s);
if(s[0]=='A')
{

scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1--;
y1--;
for(int j=1;j<=k;j++)
{
if(v[j]!=o[j])
{
int t=o[j]-v[j];
for(int u=0;u<p[j].size();u++)
{
add(p[j][u].x,p[j][u].y,t*(p[j][u].w));
}
}
o[j]=v[j];
}
ll ans=0;
ans=sum(x2,y2)-sum(x1,y2)-sum(x2,y1)+sum(x1,y1);
printf("%I64d\n",ans);
}
else
{

scanf("%d",&e);
v[e]=!v[e];
}
}
return 0;
}