大雪过后,KK决定在春秋大道的某些区间上堆雪人。现在KK遇到了一道统计雪人高度的难题,请你帮帮他吧。注:KK堆雪人前春秋大道上是没有雪人的即所有位置雪人高度为0。
大雪过后,KK决定在春秋大道的某些区间上堆雪人。现在KK遇到了一道统计雪人高度的难题,请你帮帮他吧。注:KK堆雪人前春秋大道上是没有雪人的即所有位置雪人高度为0。
给定一个整数t,表示有t(t<=5)组测试数据。每组测试数据有两个整数N(1<=N<=200000),表示N次操作。
操作分四种:
U1 x y v [x, y]位置的雪人高度减v
U2 x y v [x, y]位置的雪人高度加v
Q1 x y 查询[x, y]之间雪人的最大高度
Q2 x y 查询[x, y]之间雪人的最小高度
注: (|x|, |y|<=2^30, |v|<=100)
若上面的操作使某个位置的雪人高度为负,我们认为这种情况是合法的。
对每个查询输出结果,结果占一行。结果保证不会超int。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; struct stu{ int l,r,maxn,minn,c; int mid(){ return (l+r)>>1; } }; stu node[200010<<3]; int x[200000+10]; int y[200000+10]; int v[200000+10]; int mark[200000+10]; int li[200010<<2]; void build(int i,int l,int r){ node[i].l=l; node[i].r=r; node[i].maxn=0; node[i].minn=0; node[i].c=0; if(r==l){ return ; } int m=node[i].mid(); build(i<<1,l,m); build(i<<1|1,m+1,r); } void PUTUP(int i){ node[i].maxn=max(node[i<<1].maxn,node[i<<1|1].maxn); node[i].minn=min(node[i<<1].minn,node[i<<1|1].minn); } void PUTDOWN(int i){ if(node[i].c){ node[i<<1].c+=node[i].c; node[i<<1|1].c+=node[i].c; node[i<<1].maxn+=node[i].c; node[i<<1].minn+=node[i].c; node[i<<1|1].maxn+=node[i].c; node[i<<1|1].minn+=node[i].c; node[i].c=0; } } void updata(int i,int l,int r,int v){ if(node[i].l==l&&node[i].r==r){ node[i].c+=v; node[i].maxn+=v; node[i].minn+=v; return ; } PUTDOWN(i); int m=node[i].mid(); if(r<=m)updata(i<<1,l,r,v); else{ if(l>m)updata(i<<1|1,l,r,v); else{ updata(i<<1,l,m,v); updata(i<<1|1,m+1,r,v); } } PUTUP(i); } int query(int i,int l,int r,int w){ if(node[i].l==l&&node[i].r==r){ if(w==1) return node[i].maxn; else return node[i].minn; } PUTDOWN(i); int m=node[i].mid(); if(r<=m) return query(i<<1,l,r,w); else{ if(l>m)return query(i<<1|1,l,r,w); else{ if(w==1) return max(query(i<<1,l,m,w),query(i<<1|1,m+1,r,w)); else return min(query(i<<1,l,m,w),query(i<<1|1,m+1,r,w)); } } } int find(int l,int r,int x){ while(l<=r) { int mid=(l+r)>>1; if(li[mid]==x) return mid; if(li[mid]>x) r=mid-1; else l=mid+1; } } int main(){ int t,k,n; char s[5]; scanf("%d",&t); while(t--){ k=0; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%s",s); if(strcmp(s,"U1")==0){ mark[i]=1; scanf("%d%d%d",&x[i],&y[i],&v[i]); } else if(strcmp(s,"U2")==0){ mark[i]=2; scanf("%d%d%d",&x[i],&y[i],&v[i]); } else if(strcmp(s,"Q1")==0){ mark[i]=3; scanf("%d%d",&x[i],&y[i]); } else{ mark[i]=4; scanf("%d%d",&x[i],&y[i]); } li[++k]=x[i]; li[++k]=y[i]; } sort(li+1,li+k+1); //printf("%d %d %d %d",li[1],li[2],li[3],li[4]); int j=2; for(int i=2;i<=k;i++){ if(li[i]!=li[i-1]){ li[j++]=li[i]; } } build(1,1,j-1); for(int i=0;i<n;i++){ int l=find(1,j-1,x[i]); int r=find(1,j-1,y[i]); if(l>r){ int tem=l; l=r; r=tem; } if(mark[i]==1){ updata(1,l,r,-v[i]); } else if(mark[i]==2){ updata(1,l,r,v[i]); } else if(mark[i]==3){ printf("%d\n",query(1,l,r,1)); } else{ printf("%d\n",query(1,l,r,2)); } } } return 0; }
大雪过后,KK决定在春秋大道的某些区间上堆雪人。现在KK遇到了一道统计雪人高度的难题,请你帮帮他吧。注:KK堆雪人前春秋大道上是没有雪人的即所有位置雪人高度为0。
给定一个整数t,表示有t(t<=5)组测试数据。每组测试数据有两个整数N(1<=N<=200000),表示N次操作。
操作分四种:
U1 x y v [x, y]位置的雪人高度减v
U2 x y v [x, y]位置的雪人高度加v
Q1 x y 查询[x, y]之间雪人的最大高度
Q2 x y 查询[x, y]之间雪人的最小高度
注: (|x|, |y|<=2^30, |v|<=100)
若上面的操作使某个位置的雪人高度为负,我们认为这种情况是合法的。
对每个查询输出结果,结果占一行。结果保证不会超int。