1721: 感恩节KK专场——雪人的高度
时间限制: 1 Sec 内存限制: 128 MB提交: 88 解决: 39
[ 提交][ 状态][ 讨论版]
题目描述
大雪过后,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;
}
1721: 感恩节KK专场——雪人的高度
时间限制: 1 Sec 内存限制: 128 MB提交: 88 解决: 39
[ 提交][ 状态][ 讨论版]
题目描述
大雪过后,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。