题意:
维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.
题解:
考虑转化,先将查询看成前缀和的查询(左下角的和)。那么对一个查询
i
产生影响
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int Maxn=2e5+50;
streambuf *ib,*ob;
inline int read()
{
char ch=ib->sbumpc();int i=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();}
while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=ib->sbumpc();}
return i*f;
}
int buf[50];
inline void W(int x)
{
if(!x){ob->sputc('0');return;}
if(x<0){ob->sputc('-');x=-x;}
while(x)buf[++buf[0]]=x%10,x/=10;
while(buf[0])ob->sputc('0'+buf[buf[0]--]);
}
int s,n,cnt,cnt2,ans[Maxn],bit[Maxn],limy,t,w;
pii b[Maxn],c[Maxn];
struct node
{
int a,b,val,type,id;
}q[Maxn],tmp[Maxn];
inline void insert(int pos,int val){for(;pos<=limy;pos+=(pos&(-pos)))bit[pos]+=val;}
inline int query(int pos)
{
int res=0;
for(;pos;pos-=(pos&(-pos)))res+=bit[pos];
return res;
}
inline void solve(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
solve(l,mid);
solve(mid+1,r);
int head1=l,head2=mid+1,pos=l;
for(int i=l;i<=r;i++)tmp[i]=q[i];
while(head1<=mid&&head2<=r)
{
if(tmp[head1].a<=tmp[head2].a)
{
if(tmp[head1].type==1)insert(tmp[head1].b,tmp[head1].val);;
q[pos++]=tmp[head1++];
}
else
{
if(tmp[head2].type!=1)ans[tmp[head2].id]+=((tmp[head2].type==2)?1:(-1))*query(tmp[head2].b);
q[pos++]=tmp[head2++];
}
}
while(head1<=mid)
{
if(tmp[head1].type==1)insert(tmp[head1].b,tmp[head1].val);;
q[pos++]=tmp[head1++];
}
while(head2<=r)
{
if(tmp[head2].type!=1)ans[tmp[head2].id]+=((tmp[head2].type==2)?1:(-1))*query(tmp[head2].b);
q[pos++]=tmp[head2++];
}
for(int i=l;i<=mid;i++)
if(tmp[i].type==1)insert(tmp[i].b,-tmp[i].val);
}
int main()
{
ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);ib=cin.rdbuf();ob=cout.rdbuf();
s=read();w=read();
while(1)
{
int x=read();
if(x==1)
{
++cnt;
b[cnt].first=read();b[cnt].second=cnt;
c[cnt].first=read();c[cnt].second=cnt;
q[cnt].val=read();q[cnt].type=1;
}
else if(x==2)
{
int x1=read(),y1=read(),x2=read(),y2=read();
++cnt2;
if(x1>1&&y1>1)
{
++cnt;
b[cnt].first=x1-1;b[cnt].second=cnt;
c[cnt].first=y1-1;c[cnt].second=cnt;
q[cnt].id=cnt2;q[cnt].type=2;
}
if(x1>1)
{
++cnt;
b[cnt].first=x1-1;b[cnt].second=cnt;
c[cnt].first=y2;c[cnt].second=cnt;
q[cnt].id=cnt2;q[cnt].type=3;
}
if(y1>1)
{
++cnt;
b[cnt].first=x2;b[cnt].second=cnt;
c[cnt].first=y1-1;c[cnt].second=cnt;
q[cnt].id=cnt2;q[cnt].type=3;
}
++cnt;
b[cnt].first=x2;b[cnt].second=cnt;
c[cnt].first=y2;c[cnt].second=cnt;
q[cnt].id=cnt2;q[cnt].type=2;
}
else break;
}
sort(b+1,b+cnt+1);sort(c+1,c+cnt+1);
t=0;
for(int i=1;i<=cnt;i++)
{
if(i==1||b[i].first!=b[i-1].first)t++;
q[b[i].second].a=t;
}
t=0;
for(int i=1;i<=cnt;i++)
{
if(i==1||c[i].first!=c[i-1].first)t++;
q[c[i].second].b=t;
}
limy=t;
solve(1,cnt);
for(int i=1;i<=cnt2;i++)W(ans[i]),ob->sputc('\n');
}