一道常规的二维偏序,用前缀和的思想把求分成
带修改条件的,是从二维进阶到三维的必备题
#include<cstdio>
using namespace std;
const int N=2e6+5;
int n,m,c,cnt,ans[N];
struct A{int id,k,x,y; }q[N],t[N];
void work(int l,int r)
{
if(l==r) return;
int mid=l+r>>1;
work(l,mid),work(mid+1,r);
int i=l,j=mid+1,k=l,y=0;
while(i<=mid&&j<=r)
{
if(q[i].x<=q[j].x)
{
t[k++]=q[i];
if(q[i].k==1) y+=q[i].y;
i++;
} else
{
t[k++]=q[j];
if(q[j].k==2) ans[q[j].id]-=y;
else if(q[j].k==3) ans[q[j].id]+=y;
j++;
}
}
while(i<=mid) t[k++]=q[i++];
while(j<=r)
{
t[k++]=q[j];
if(q[j].k==2) ans[q[j].id]-=y;
else if(q[j].k==3) ans[q[j].id]+=y;
j++;
}
for(int i=l;i<=r;i++) q[i]=t[i];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int x; scanf("%d",&x);
q[++c]=(A){0,1,i,x};
}
for(int i=1;i<=m;i++)
{
int k,x,y; scanf("%d%d%d",&k,&x,&y);
if(k==1) q[++c]=(A){0,k,x,y};
else q[++c]=(A){++cnt,2,x-1,0},q[++c]=(A){cnt,3,y,0};
}
work(1,c);
for(int i=1;i<=cnt;i++) printf("%d\n",ans[i]);
return 0;
}