hpu--1721(离散化)

来源:互联网 发布:高仿表 知乎 编辑:程序博客网 时间:2024/04/29 22:11


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。

样例输入

12U2 -1000 1000 1Q1 1000 10001

样例输出

1


解题思路:第一道线段树离散化,模仿了大神的方法,对离散化操作有了一丢丢的的了解。

代码如下:
#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。

样例输入

12U2 -1000 1000 1Q1 1000 10001

样例输出

1
0 0
原创粉丝点击