题目来源:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=134851
输入:
10 10 5
state 0
groupchange 2 9 7
state 9
groupchange 0 2 10
change 0 -5
输出:
0
7
7
3
-3
题意:
输入:n,top,Q (1<=n<=4587520,1<=top<=1000,1<=Q<=50000)
n为10个初值为0的数,top是最大限制(后面会提),Q,操作数。
state:0 当前0下标,数值是多少。输出
groupchange : 2 9 7 更新区间[2,9] 的值,最多加7,和不能大于top。输出能加的值。
change:0 -5 下标为0的数,最多加-5,结果不能<0;输出能加的值。
思路:线段树,更新查找。(维护区间最大值最小值)
<pre name="code" class="cpp">#include<iostream> #include<cstdio> #include<cstring> #define maxn 5000000 #define INF 1147483648 using namespace std; int max(int x,int y) {return x>y?x:y;} int min(int x,int y) {return x<y?x:y;} int mmax,mmin; struct data { int l,r,minv,maxv,cover,add; }tree[4*maxn]; void build(int u,int L,int R) { tree[u].l = L; tree[u].r=R; tree[u].add=0; tree[u].cover=0; tree[u].minv=0; tree[u].maxv=0; if(L==R) return; int M=(R+L)/2; build(u<<1,L,M); build((u<<1)+1,M+1,R); tree[u].minv=min(tree[u<<1].minv, tree[(u<<1)+1].minv); tree[u].maxv=max(tree[u<<1].maxv, tree[(u<<1)+1].maxv); } void get_down(int u) { tree[u<<1].minv+=tree[u].add; tree[u<<1].maxv+=tree[u].add; tree[u<<1].add+=tree[u].add; tree[u<<1].cover=1; tree[(u<<1)+1].minv+=tree[u].add; tree[(u<<1)+1].maxv+=tree[u].add; tree[(u<<1)+1].add+=tree[u].add; tree[(u<<1)+1].cover=1; tree[u].cover=0; tree[u].add=0; } void update(int u,int ql,int qr,int v) { if(tree[u].l==ql&&tree[u].r==qr) { tree[u].minv+=v; tree[u].maxv+=v; tree[u].add+=v; tree[u].cover=1; return ; } int mid=(tree[u].l+tree[u].r)/2; if(qr<=mid) update(u<<1,ql,qr,v); else if(ql>= mid+1) update((u<<1)+1,ql,qr,v); else { update(u<<1,ql,mid,v); update((u<<1)+1,mid+1,qr,v); } //需要维护父亲节点 tree[u].minv=min(tree[u<<1].minv, tree[(u<<1)+1].minv); tree[u].maxv=max(tree[u<<1].maxv, tree[(u<<1)+1].maxv); } void query(int u,int ql,int qr) { if(tree[u].l==ql&&tree[u].r==qr) { mmax=max(mmax,tree[u].maxv); mmin=min(mmin,tree[u].minv); return ; } if(tree[u].cover) get_down(u); int mid=(tree[u].l+tree[u].r)/2; if(qr<=mid) query(u<<1,ql,qr); else if(ql>=mid+1) query((u<<1)+1,ql,qr); else { query(u<<1,ql,mid); query((u<<1)+1,mid+1,qr); } } int main() { int n,top,Q; char str[100]; int a,b,x; while(scanf("%d%d%d",&n,&top,&Q)!=EOF) { build(1,1,n); while(Q--) { scanf("%s",str); if(str[0]=='s') { scanf("%d",&a); a++; mmax=0; mmin=INF; query(1,a,a); printf("%d\n",mmin); } if(str[0]=='g') { scanf("%d%d%d",&a,&b,&x); a++;b++; mmax=0; mmin=INF; query(1,a,b); if(x<=0) { if(x+mmin<0) { int t=mmin*-1; update(1,a,b,t); printf("%d\n",t); } else { update(1,a,b,x); printf("%d\n",x); } } else { if(mmax+x>top) { int t=top-mmax; update(1,a,b,t); printf("%d\n",t); } else { update(1,a,b,x); printf("%d\n",x); } } } if(str[0]=='c') { scanf("%d%d",&a,&x); a++; mmax=0; mmin=INF; query(1,a,a); if(x<=0) { if(x+mmin<0) { int t=-1*mmin; update(1,a,a,t); printf("%d\n",t); } else { update(1,a,a,x); printf("%d\n",x); } } else { if(x+mmax>top) { int t=top-mmax; update(1,a,a,t); printf("%d\n",t); } else { update(1,a,a,x); printf("%d\n",x); } } } } } return 0; }