标签:mes 端点 线段树 线段 down turn max 题解 操作
# 题意
初始只有m个数字,m个操作Q表示查询序列后L个数的最大值,A t表示在序列后加一个数长度变为n+1,
加的数是(t+a)mod p,a是上一次查询的值
# 题解
线段树操作即可,只需要向上更新属性,额外记录数组个数和上一次查询值
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=2e5+10; 4 struct node{ 5 int l,r; 6 int v; 7 }tr[4*N]; 8 9 inline void push_up(int u){//从下向上更新信息 10 tr[u].v=max(tr[u<<1].v,tr[u<<1|1].v); 11 } 12 //void push_down(int u){//延迟标记,从上向下更新 13 14 //} 15 inline void build(int u,int l,int r){ 16 tr[u].l=l,tr[u].r=r; 17 if(l==r) { 18 return; 19 } 20 int mid=l+r>>1; 21 build(u<<1,l,mid); 22 build(u<<1|1,mid+1,r); 23 } 24 inline void change(int u,int x,int v){ // 单点修改将a[x]值改为v 25 if(tr[u].l==x && tr[u].r ==x){ 26 tr[u].v=v; 27 } 28 else{ 29 int mid=tr[u].l+tr[u].r>>1; 30 if(x <= mid) change(u<<1,x,v); 31 else change(u<<1|1,x,v); 32 push_up(u); 33 } 34 } 35 inline int ask(int u,int l,int r){ 36 if(tr[u].l>=l && tr[u].r<=r) return tr[u].v; 37 int mid = tr[u].l + tr[u].r >> 1; 38 int v=0;//负无穷 39 if(l<=mid)//中点在左端点右边 40 v=ask(u<<1,l,r); 41 if(r>mid) //中点在右端点左边 42 v=max(v,ask(u<<1|1,l,r)); 43 return v; 44 } 45 int m,p; 46 int main(){ 47 cin>>m>>p; 48 int n=0,last=0; 49 build(1,1,m); 50 int x; 51 string op; 52 while(m--) { 53 cin >> op >> x; 54 if(op[0]==‘Q‘){ 55 last=ask(1,n-x+1,n); 56 cout<<last<<endl; 57 } 58 else { 59 change(1,n+1,(x+last)%p); 60 n++; 61 } 62 } 63 64 }
标签:mes 端点 线段树 线段 down turn max 题解 操作
原文地址:https://www.cnblogs.com/hhyx/p/12459979.html