1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<LL,int> PLI; const LL mod=2000000239; const LL A=2000000137; const int N=2e5+5; const int NN=4e5+5; const int B=950; int n,q; void getz(int &x){ x=0;int f=1;char c=getchar(); while(c>'9' || c<'0')c=='-'?f=-1:1,c=getchar(); while(c<='9' && c>='0')x=(x<<3)+(x<<1)+c-'0',c=getchar(); x=x*f; } LL mt(LL x){return x>=mod?x-mod:(x<0?x+mod:x);} struct Hash{ LL fb[N],ff[N]; void init(){ fb[0]=1;fb[1]=A; for(int i=2;i<=n;i++)fb[i]=fb[i-1]*A%mod; ff[0]=1;for(int i=1;i<=n;i++)ff[i]=mt(ff[i-1]+fb[i]); } }has; PLI operator+(PLI x,PLI y){ return {(x.first*has.fb[y.second]+y.first)%mod,x.second+y.second}; } int bel[N],lazy[N],ll[N],rr[N],val[N]; PLI fl[N]; void maintain(int x){ for(int i=ll[x];i<=rr[x];i++){ if(i==ll[x])fl[i]=PLI{val[i],1}; else fl[i]=fl[i-1]+PLI{val[i],1}; } } void change(int x,int l,int r,int d){ for(int i=ll[x];i<=rr[x];i++){ val[i]+=lazy[x]; if(i>=l && i<=r)val[i]+=d; } lazy[x]=0; maintain(x); } void change(int l,int r,int d){ if(bel[l]==bel[r])change(bel[l],l,r,d); else{ change(bel[l],l,r,d); change(bel[r],l,r,d); for(int i=bel[l]+1;i<bel[r];i++)lazy[i]+=d; } } PLI queryhash_nl(int l,int r){ if(l==ll[bel[l]])return fl[r]; else return {mt(fl[r].first-fl[l-1].first*has.fb[ r-l+1 ]%mod),r-l+1}; } PLI hashplus(PLI x,LL d){return {mt(x.first+has.ff[x.second-1]*d%mod),x.second};} PLI queryhash_l(int l,int r){return hashplus(queryhash_nl(l,r),lazy[bel[l]]);} PLI queryhas(int l,int r){ PLI ans={0ll,0}; for(int i=bel[l];i<=bel[r];i++){ ans=ans+queryhash_l(max(l,ll[i]),min(rr[i],r)); } return ans; } bool cmp(int x,int y,int lim,int typ=0){ int l=1,r=lim-max(x,y)+1,mid,ans=0; while(l<=r){ mid=(l+r)>>1; if(queryhas(x,x+mid-1)!=queryhas(y,y+mid-1))r=mid-1; else l=mid+1,ans=mid; } if(ans==lim-max(x,y)+1)return typ?x<y:x>y; else return val[x+ans]+lazy[bel[x+ans]]<val[y+ans]+lazy[bel[y+ans]]; } struct Segment{ int lc,rc; vector<int> sign; }tr[NN];int cnt; void updata(int x,int r){ tr[x].sign=tr[tr[x].rc].sign; int ans=0; for(auto y:tr[tr[x].lc].sign){ if(!ans || cmp(y,ans,r,1))ans=y; } tr[x].sign.push_back(ans); } int bt(int l,int r){ int x=++cnt; if(l==r)tr[x].sign.push_back(l); else{ int mid=(l+r)>>1; tr[x].lc=bt(l,mid); tr[x].rc=bt(mid+1,r); updata(x,r); } return x; } void change(int x,int l,int r,int ll,int rr){ if(ll>rr || rr<l || ll>r || (l>=ll && r<=rr))return ; int mid=(l+r)>>1; change(tr[x].lc,l,mid,ll,rr); change(tr[x].rc,mid+1,r,ll,rr); updata(x,r); } int zans; void query(int x,int l,int r,int ll,int rr){ if(ll>rr || rr<l || ll>r)return ; if(l>=ll && r<=rr){ for(auto y:tr[x].sign){ if(!zans || cmp(y,zans,rr))zans=y; } return ; } int mid=(l+r)>>1; query(tr[x].lc,l,mid,ll,rr); query(tr[x].rc,mid+1,r,ll,rr); } int main(){ getz(n);getz(q); has.init(); for(int i=1;i<=n;i++){ getz(val[i]); val[i]+=1000000001; } for(int i=1;i<=n;i++){ bel[i]=i/B+1; if(!ll[bel[i]])ll[bel[i]]=i; rr[bel[i]]=i; } for(int i=1;i<=bel[n];i++)maintain(i); bt(1,n); for(int i=1;i<=q;i++){ int typ;getz(typ); if(typ==1){ int l,r,d;getz(l);getz(r);getz(d); change(l,r,d); change(1,1,n,l,r); } else{ int l,r;getz(l);getz(r); zans=0; query(1,1,n,l,r); printf("%d\n",zans); } } return 0; }
|