luogu5012 水の数列 (并查集+线段树)
如果我们能求出来每个区间个数的最大分值,那就可以用线段树维护这个东西 然后出答案了
然后这个的求法和(luogu4269)Snow Boots G非常类似,就是我们把数大小排个序,每次都拿<=x的位置去合并那个并查集,同时维护个数和大小
1 #pragma GCC optimize(3) 2 #include<bits/stdc++.h> 3 #define pa pair<double,int> 4 #define CLR(a,x) memset(a,x,sizeof(a)) 5 using namespace std; 6 typedef long long ll; 7 const int maxn=1e6+10; 8 9 inline char gc(){ 10 return getchar(); 11 static const int maxs=1<<16;static char buf[maxs],*p1=buf,*p2=buf; 12 return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxs,stdin),p1==p2)?EOF:*p1++; 13 } 14 inline ll rd(){ 15 ll x=0;char c=gc();bool neg=0; 16 while(c<'0'||c>'9'){if(c=='-') neg=1;c=gc();} 17 while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=gc(); 18 return neg?(~x+1):x; 19 } 20 21 struct Node{ 22 int v,i; 23 }p[maxn]; 24 int fa[maxn],siz[maxn],N,T; 25 pa ma[maxn<<2]; 26 bool flag[maxn]; 27 int nowcnt; 28 ll nowsum; 29 30 inline bool cmp(Node a,Node b){return a.v<b.v;} 31 32 inline int getf(int x){return x==fa[x]?x:getf(fa[x]);} 33 34 inline void uni(int x){ 35 flag[x]=1;siz[x]=1; 36 nowcnt++; 37 if(flag[x-1]){ 38 int a=getf(x-1); 39 nowsum-=1ll*siz[a]*siz[a],siz[x]+=siz[a],fa[a]=x; 40 nowcnt--; 41 }if(flag[x+1]){ 42 int b=getf(x+1); 43 nowsum-=1ll*siz[b]*siz[b],siz[x]+=siz[b],fa[b]=x; 44 nowcnt--; 45 }nowsum+=1ll*siz[x]*siz[x]; 46 } 47 48 inline void update(int p){ma[p]=max(ma[p<<1],ma[p<<1|1]);} 49 50 inline void change(int p,int l,int r,int x,pa y){ 51 if(l==r) ma[p]=max(ma[p],y); 52 else{ 53 int m=l+r>>1; 54 if(x<=m) change(p<<1,l,m,x,y); 55 else change(p<<1|1,m+1,r,x,y); 56 update(p); 57 } 58 } 59 60 inline pa query(int p,int l,int r,int x,int y){ 61 if(x<=l&&r<=y) return ma[p]; 62 int m=l+r>>1;pa re=make_pair(0,0); 63 if(x<=m) re=query(p<<1,l,m,x,y); 64 if(y>=m+1) re=max(re,query(p<<1|1,m+1,r,x,y)); 65 return re; 66 } 67 68 int main(){ 69 //freopen("","r",stdin); 70 int i,j,k; 71 N=rd(),T=rd(); 72 for(i=1;i<=N;i++){ 73 p[i].v=rd(),p[i].i=i; 74 }sort(p+1,p+N+1,cmp); 75 for(i=1;i<=N;i++) fa[i]=i; 76 for(i=1;i<=N;i++){ 77 uni(p[i].i); 78 if(p[i].v!=p[i+1].v) change(1,1,N,nowcnt,make_pair(1.0*nowsum/p[i].v,p[i].v)); 79 } 80 ll lastans=0; 81 for(i=1;i<=T;i++){ 82 ll a=rd(),b=rd(),x=rd(),y=rd(); 83 int l=(a*lastans+x-1)%N+1,r=(b*lastans+y-1)%N+1; 84 if(l>r) swap(l,r); 85 pa re=query(1,1,N,l,r); 86 if(re.first==0){ 87 printf("-1 -1\n"); 88 }else 89 printf("%lld %d\n",(ll)(re.first*re.second+0.5),re.second); 90 printf("%d %d %d\n",l,r,lastans); 91 if(re.first==0) lastans=1; 92 else lastans=((ll)(re.first*re.second+0.5))%N*re.second%N; 93 } 94 return 0; 95 }