• 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
    ");
    88         }else
    89             printf("%lld %d
    ",(ll)(re.first*re.second+0.5),re.second);
    90         printf("%d %d %d
    ",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 }
  • 相关阅读:
    手风琴效果
    开关门
    常用的一些获取尺寸的方法
    话话js中的事件监听
    数组去重
    百度地图 之 热力图
    小程序 之 百度智能小程序(第二章)
    小程序 之 百度智能小程序(第一章)
    javascript 之 继承与闭包
    浅谈prototype与__proto__、constructor三者之间的关系
  • 原文地址:https://www.cnblogs.com/Ressed/p/9934947.html
Copyright © 2020-2023  润新知