題目來源: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;
}