• 倍增并查集


    适用于一个区间向另一个区间连边,形如:

    for(int i=1;i<=r1-l1+1;++i)
        merge(l1+i-1,l2+i-1);

    开log个并查集,用表示的区间左端点编号,合并的时候像RMQ一样拆区间,递归即可

    每个$2^i$的i最多合并$n-1$次,复杂度$O(n*logn)$

    萌萌哒:

    统计最后的集合个数x,答案为$10^{x-1}*9$

     1 #include<bits/stdc++.h>
     2 #define MAXN 100005
     3 #define LL long long
     4 using namespace std;
     5 const int mod=1e9+7;
     6 inline int read(){
     7     int s=0,w=0;char ch=getchar();
     8     while(ch<'0'||ch>'9')w|=(ch=='-'),ch=getchar();
     9     while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
    10     return w?-s:s;
    11 }
    12 #define kd (read())
    13 inline int qpow(int a,int b){
    14     int res=1;
    15     for(;b;b>>=1,a=(LL)a*a%mod)
    16         if(b&1)res=(LL)res*a%mod;
    17     return res;
    18 }
    19 int n,m;
    20 int fat[18][MAXN],LOG[MAXN];
    21 inline int find(int x,int I){
    22     return fat[I][x]=fat[I][x]==x?x:find(fat[I][x],I);
    23 }
    24 int sum=0;
    25 void fenzhi(int x,int y,int I){
    26     if(find(x,I)==find(y,I))return ;
    27     fat[I][find(x,I)]=find(y,I);
    28     if(!I)return sum--,void();
    29     fenzhi(x,y,I-1);
    30     fenzhi(x+(1<<I-1),y+(1<<I-1),I-1);
    31     return ;
    32 }
    33 int main(){
    34     n=kd;m=kd;
    35     for(int i=2;i<=n;++i)
    36         LOG[i]=LOG[i>>1]+1;
    37     for(int i=1;i<=n;++i)
    38         for(int j=0;j<18;++j)
    39             fat[j][i]=i;
    40     sum=n;
    41     int l1,l2,r1,r2,k;
    42     while(m--){
    43         l1=kd,r1=kd,l2=kd,r2=kd;
    44         k=LOG[r1-l1+1];
    45         fenzhi(l1,l2,k);
    46         fenzhi(r1-(1<<k)+1,r2-(1<<k)+1,k);
    47     }printf("%d
    ",9LL*qpow(10,sum-1)%mod);
    48     return 0;
    49 }
    View Code

    Endless:

    平方串套路对于每个长度$x$,标记$frac{n}{x}$个关键点,每个关键点$i$,统计$i$和$i-1$的最长公共后缀+$i$和$i+1$的最长公共前缀,得到的区间所有长度为二倍$x$的串都是平方串,用$hash$二分或者$sa$,然后倍增并查集。因为考虑最小生成树,所以x按权值排序枚举,每次递归到$2^0$以为着加边。

      1 #include<bits/stdc++.h>
      2 #define MAXN 300005
      3 #define LL long long
      4 using namespace std;
      5 const LL mo1=1e9+7,mo2=998244353,p=1e6;
      6 inline int read(){
      7     int s=0,w=0;char ch=getchar();
      8     while(ch<'0'||ch>'9')w|=(ch=='-'),ch=getchar();
      9     while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
     10     return w?-s:s;
     11 }
     12 #define kd (read())
     13 int n;
     14 int a[MAXN];
     15 int LOG[MAXN];
     16 int fat[20][MAXN];
     17 LL qsm1[MAXN],qsm2[MAXN],bin1[MAXN],bin2[MAXN];
     18 inline LL cal1(int l,int r){
     19     return (qsm1[r]-qsm1[l-1]*bin1[r-l+1]%mo1+mo1)%mo1;
     20 }
     21 inline LL cal2(int l,int r){
     22     return (qsm2[r]-qsm2[l-1]*bin2[r-l+1]%mo2+mo2)%mo2;
     23 }
     24 struct node{
     25     int len,val;
     26     friend bool operator <(const node &a,const node &b){
     27         return a.val<b.val;
     28     }
     29 }Q[MAXN>>1];
     30 inline int find(int x,int I){
     31     return fat[I][x]==x?x:fat[I][x]=find(fat[I][x],I);
     32 }
     33 long long ans=0;
     34 void fenzhi(int x,int y,int I,int w){
     35     if(find(x,I)==find(y,I))return ;
     36     fat[I][find(x,I)]=find(y,I);
     37     if(!I)return ans+=w,void();
     38     fenzhi(x,y,I-1,w),fenzhi(x+(1<<I-1),y+(1<<I-1),I-1,w);
     39     return ;
     40 }
     41 void merge(int l1,int r1,int l2,int r2,int w){
     42     int k=LOG[r1-l1+1];
     43     fenzhi(l1,l2,k,w),fenzhi(r1-(1<<k)+1,r2-(1<<k)+1,k,w);
     44     return ;
     45 }
     46 void work(){
     47     n=kd;ans=0;
     48     for(int i=1;i<=n;++i){
     49         a[i]=kd;
     50         qsm1[i]=(qsm1[i-1]*p%mo1+a[i])%mo1;
     51         qsm2[i]=(qsm2[i-1]*p%mo2+a[i])%mo2;
     52         for(int j=0;j<=19;++j)fat[j][i]=i;
     53     }
     54     for(int i=1;i<=(n>>1);++i)
     55         Q[i].val=kd,Q[i].len=i;
     56     sort(Q+1,Q+(n>>1)+1);
     57     for(int I=1;I<=(n>>1);++I){
     58         int len=Q[I].len,w=Q[I].val;
     59         //cout<<len<<" "<<w<<endl;
     60         for(int i=1;i<=n;i+=len){
     61             int L,R;
     62             if(i!=1){
     63                 int rr=min(i+len-1,n);
     64                 int l=0,r=min(len,min(i+len-1,n)-i+1);
     65                 while(r-l>1){
     66                     int mid=l+r>>1;
     67                     if(cal1(rr-mid+1,rr)==cal1(i-1-mid+1,i-1)
     68                      &&cal2(rr-mid+1,rr)==cal2(i-1-mid+1,i-1))
     69                         l=mid;
     70                     else r=mid;
     71                 }
     72                 if(cal1(rr-r+1,rr)==cal1(i-1-r+1,i-1)
     73                  &&cal2(rr-r+1,rr)==cal2(i-1-r+1,i-1))
     74                 L=i-1-r+1;
     75                 else L=i-1-l+1;
     76             }else L=i;
     77             if(i+len<=n){
     78                 int l=0,r=min(len,min(i+2*len-1,n)-(i+len)+1);
     79                 while(r-l>1){
     80                     int mid=l+r>>1;
     81                     if(cal1(i,i+mid-1)==cal1(i+len,i+len+mid-1)
     82                      &&cal2(i,i+mid-1)==cal2(i+len,i+len+mid-1))
     83                         l=mid;
     84                     else r=mid;
     85                 }
     86                 if(cal1(i,i+r-1)==cal1(i+len,i+len+r-1)
     87                  &&cal2(i,i+r-1)==cal2(i+len,i+len+r-1))
     88                 R=i+len+r-1;
     89                 else R=i+len+l-1;
     90             }else R=min(i+len-1,n);
     91             //cout<<"HH "<<i<<" "<<L<<" "<<R<<endl;
     92             if(R-L+1>=2*len){
     93                 //cout<<L<<" "<<R-len<<" "<<L+len<<" "<<R<<endl;
     94                 merge(L,R-len,L+len,R,w);
     95             }
     96         }
     97     }printf("%lld
    ",ans);
     98     return ;
     99 }
    100 int main(){
    101     //freopen("1.in","r",stdin);
    102     freopen("endless.in","r",stdin);
    103     freopen("endless.out","w",stdout);
    104     bin1[0]=bin2[0]=1;
    105     for(int i=1;i<=3e5;++i)bin1[i]=bin1[i-1]*p%mo1,bin2[i]=bin2[i-1]*p%mo2;
    106     for(int i=2;i<=3e5;++i)LOG[i]=LOG[i>>1]+1;
    107     int T=kd;
    108     while(T--)work();
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    sql,linq基础再一次学习
    position与aop
    java基础常用类!
    JNI初步!
    java基础动态代理!
    java基础面向对象!
    php初步!
    java基础泛型!
    java基础对象多态性!
    java基础io流!
  • 原文地址:https://www.cnblogs.com/2018hzoicyf/p/13068533.html
Copyright © 2020-2023  润新知