JD2943——线段树、树套树、分块(线段树裸题)

来源:互联网 发布:惠州网络车问政平台 编辑:程序博客网 时间:2024/06/07 13:59

Description

给出一个序列,要求支持以下操作:
1 x y : 输出[x,y]中最大的数字。
2 x y : 将序列的第x个数字改成y。

Input

第一行一个整数n,表示数列的长度。
第二行n个数,表示初始的序列。
第三行一个整数m,表示操作数量。
接下来m行,每行可能是1 x y,或者2 x y,意义如上。
强制在线,记上一次输出的答案为last_ans(last_ans初值为0):
对于第一个操作1 x y
x = min((x + last_ans) % n + 1, (y + last_ans) % n + 1)
y = max((x + last_ans) % n + 1, (y + last_ans) % n + 1)
对于第二个操作2 x y
x = (x + last_ans) % n + 1
y = (y + last_ans) % n + 1

Output

对于每个1操作,输出[x,y]中的最大值。

Sample Input

1010 4 6 2 3 1 8 3 5 751 4 52 5 92 9 51 2 101 1 1

Sample Output

333

HINT

n, m <= 100000

BY JYZ



#include<stdio.h>int mt[400001],n,m,l,x,y;int max(int a,int b){if(a>b)return a;return b;}int min(int a,int b){if(a>b)return b;return a;}void build(int k,int l,int r){if(l==r){scanf("%d",&mt[k]);return;}int mid=(l+r)>>1,p=k<<1;build(p,l,mid);build(p+1,mid+1,r);mt[k]=max(mt[p],mt[p+1]);}void dfs(int k,int l,int r,int a,int b){if(l==r){mt[k]=b;return;}int mid=(l+r)>>1,t=k<<1;if(a<=mid)dfs(t,l,mid,a,b); elsedfs(t+1,mid+1,r,a,b);mt[k]=max(mt[t],mt[t+1]);}int find(int k,int l,int r,int a,int b){if(l>=a&&r<=b)return mt[k];int mid=(l+r)>>1,t=k<<1,p=0;if(mid>=a)p=max(find(t,l,mid,a,b),p);if(mid<b)p=max(find(t+1,mid+1,r,a,b),p);return p;}int main(){scanf("%d",&n);build(1,1,n);scanf("%d",&m);for(int i=1;i<=m;i++){int a,b,s;scanf("%d%d%d",&s,&a,&b);if(s==1){x=min((a+l)%n+1,(b+l)%n+1);y=max((a+l)%n+1,(b+l)%n+1);l=find(1,1,n,x,y);printf("%d\n",l);}if(s==2){x=(a+l)%n+1;y=(b+l)%n+1;dfs(1,1,n,x,y);}}}