Description
你有一个 N×N N × N 的棋盘,每个格子内有一个整数,初始时的时候全部为 0 0 ,现在需要维护两种操作:
命令 | 参数限制 | 内容 |
---|---|---|
1<=x,y<=N 1 <= x , y <= N , A A 是正整数 | 将格子里的数字加上 A A | |
1<=x1<=x2<=N1<=y1<=y2<=N 1 <= x 1 <= x 2 <= N 1 <= y 1 <= y 2 <= N 输出 x1 y1 x2 y2 x 1 y 1 x 2 y 2 这个矩形内的数字和 3 3 | 无 | 终止程序 |
Input
输入文件第一行一个正整数。
接下来每行一个操作。
Output
对于每个 2 2 操作,输出一个对应的答案。
Sample Input
4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
HINT
,操作数不超过
200000
200000
个,内存限制
20M
20
M
。
对于
100
100
的数据,操作
1
1
中的不超过
2000
2000
。
Source
思路
把 x x 和的坐标加上操作的时间 T T <script type="math/tex" id="MathJax-Element-717">T</script>构成三维偏序。
代码
#include <cstdio>
#include <algorithm>
const int maxn=800000;
const int maxm=500000;
const int maxk=200000;
int n;
struct tree_array
{
int c[maxn+10];
inline int lowbit(int x)
{
return x&(-x);
}
inline int add(int pos,int x)
{
if(!pos)
{
return 0;
}
while(pos<=n)
{
c[pos]+=x;
pos+=lowbit(pos);
}
return 0;
}
inline int sum(int pos)
{
int res=0;
while(pos)
{
res+=c[pos];
pos-=lowbit(pos);
}
return res;
}
};
struct data
{
int x,y,id,v;
bool operator <(const data &other) const
{
return x<other.x;
}
};
int ans[maxm+10],m;
tree_array t;
data d[maxn+10];
int make_data(int a,int b,int c,int e)
{
++m;
d[m].x=a;
d[m].y=b;
d[m].id=c;
d[m].v=e;
return 0;
}
int solve(int l,int r)
{
if(l==r)
{
return 0;
}
int mid=(l+r)>>1;
solve(l,mid);
solve(mid+1,r);
std::sort(d+l,d+mid+1);
std::sort(d+mid+1,d+r+1);
int j=l;
for(register int i=mid+1; i<=r; ++i)
{
while((j<=mid)&&(d[j].x<=d[i].x))
{
t.add(d[j].y,d[j].v);
++j;
}
if(d[i].id)
{
ans[abs(d[i].id)]+=((d[i].id>0)?1:-1)*t.sum(d[i].y);
}
}
for(register int i=l; i<j; ++i)
{
t.add(d[i].y,-d[i].v);
}
return 0;
}
int tot,opt,a,b,c,e;
int main()
{
scanf("%d",&n);
while(1)
{
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d%d",&a,&b,&c);
make_data(a,b,0,c);
}
else if(opt==2)
{
++tot;
scanf("%d%d%d%d",&a,&c,&b,&e);
make_data(std::min(a,b)-1,std::min(c,e)-1,tot,0);
make_data(std::min(a,b)-1,std::max(c,e),-tot,0);
make_data(std::max(a,b),std::min(c,e)-1,-tot,0);
make_data(std::max(a,b),std::max(c,e),tot,0);
}
else
{
break;
}
}
solve(1,m);
for(register int i=1; i<=tot; ++i)
{
printf("%d\n",ans[i]);
}
return 0;
}