P1198 最大数 线段树水题
这道题模拟一下可以过,但是我们发现线段树也可以安全水过......
写的线段树只需要滋磁单点修改,区间求max即可
我一开始犯了一个很SB的错误:每次插入修改了t,然后疯狂爆0到怀疑人生...
而且我写的线段树还不明不白的碾了胡雨菲几年前写的。
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 using namespace std; 5 const int N = 200010; 6 typedef long long LL; 7 LL mo; 8 LL Max[N<<2]; 9 10 void build(int l,int r,int o) 11 { 12 Max[o]=-2147483647; 13 if(l==r) 14 { 15 return; 16 } 17 int mid=(l+r)>>1; 18 build(l,mid,o<<1); 19 build(mid+1,r,o<<1|1); 20 return; 21 } 22 23 void add(int x,int v,int l,int r,int o) 24 { 25 //printf("add:x=%d v=%d l=%d r=%d o=%d\n",x,v,l,r,o); 26 if(l==x&&r==x) 27 { 28 //printf("Max[%d]=%d\n",o,v); 29 Max[o]=v; 30 return; 31 } 32 int mid=(l+r)>>1; 33 if(x<=mid)add(x,v,l,mid,o<<1); 34 else add(x,v,mid+1,r,o<<1|1); 35 Max[o]=max(Max[o<<1],Max[o<<1|1]); 36 return; 37 } 38 39 LL ask(int L,int R,int l,int r,int o) 40 { 41 if(L<=l&&r<=R) return Max[o]; 42 if(R<l||r<L) return -2147483647; 43 int mid=(l+r)>>1; 44 return max(ask(L,R,l,mid,o<<1),ask(L,R,mid+1,r,o<<1|1)); 45 } 46 47 int main() 48 { 49 LL m,top=1,x,t=0;char flag; 50 scanf("%lld%lld",&m,&mo); 51 build(1,m,1); 52 for(int i=1;i<=m;i++) 53 { 54 cin>>flag>>x; 55 if(flag=='Q') 56 { 57 if(!x) {printf("0\n");continue;} 58 t=ask(top-x,top-1,1,m,1); 59 printf("%lld\n",t); 60 } 61 else 62 { 63 64 add(top,(t+x)%mo,1,m,1); 65 top++; 66 } 67 } 68 return 0; 69 }