zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    [2021.8集训Day10/JZOJ.3410]【GDOI2014模拟】Tree
    [2021.8集训Day10/JZOJ.3441]【NOIP2013模拟】小喵喵的新家
    [模板]模拟退火 / 洛谷 P1337 [JSOI2004]平衡点
    P1600 [NOIP2016 提高组] 天天爱跑步
    P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并
    selenium的三种等待
    python中socket、socketio、flask-socketio、WebSocket的区别与联系
    (十二)python3 迭代器
    (十一)python3 encode()和decode()
    (十)python3 生成器
  • 原文地址:https://www.cnblogs.com/Ressed/p/9934947.html
Copyright © 2011-2022 走看看