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 }

 

posted @ 2018-11-09 14:31  Ressed  阅读(171)  评论(0编辑  收藏  举报