• [BZOJ2054]疯狂的馒头 并查集


    写点题庆祝一下自己的退役。

    其实是为了学习一下并查集。

    之前校内NOIP模拟赛(别说了,NOIP已经刮掉了)有一道题可以用并查集做,但是被我用强力剪枝水过去了。

    今天发现并查集好像是个非常好用的东西,似乎还挺强大的,所以来学习一下。

    突然发现并查集这东西好像有很多好的性质,要是明年的今天没有退役的话,或许可以来出些题目。

    看到这种题如果暴力用线段树做的话那么就是显然的(O(mlog n))显然做不了。

    那么考虑时间倒流,先染后面的色,这样如果染过色了的点就不需要再染了。

    那么我们现在就是需要想个办法保证,每个该被染色的点,被且只被染一次色,这样才能有复杂度保证。

    这里介绍一个新的技巧。

    我们维护一个东西,表示这个点右边(含自己)未被染色的第一个点(fa[x])。有了这个东西我们就可以直接跳过之间那些被染过色的点。

    考虑染完色以后,他的(fa[x])的值应该是和(fa[x+1])一样的。但是,只要(fa[x+1])的值被改掉了,(fa[x])也应该一起改。

    发现这种东西可以种并查集维护。

    然后具体实现看代码吧。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define REP(i,a,n) for(register int i(a);i<=(n);++i)
    #define PER(i,a,n) for(register int i(a);i>=(n);--i)
    #define dbg(...) fprintf(stderr,__VA_ARGS__)
    template<typename A,typename B>inline char SMAX(A&a,const B&b){return a<b?a=b,1:0;}
    template<typename A,typename B>inline char SMIN(A&a,const B&b){return a>b?a=b,1:0;}
    const int SZ=(1<<21)+1;char obuf[SZ+128],*oS=obuf,*oT=obuf+SZ-1;
    inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
    #define printf(...) oS>oT&&(flush(),1),oS+=sprintf(oS,__VA_ARGS__)
    struct IO_flusher{inline~IO_flusher(){flush();}}io_flusher;
    typedef long long ll;
    
    const int N=1e6+7,M=1e7+7;
    int n,m,p,q,col[N];
    
    int fa[N],stk[N]; 
    inline int Find(int x){while(fa[x]!=x)stk[++stk[0]]=x,x=fa[x];while(stk[0])fa[stk[stk[0]--]]=x;return x;}
    int main(){
    	scanf("%d%d%d%d",&n,&m,&p,&q);
    	REP(i,1,n)fa[i]=i;fa[n+1]=n+1;//错误笔记:Very important!!! 必须要把n+1自己存一下
    	PER(i,m,1){
    		int l=((ll)i*p+q)%n+1,r=((ll)i*q+p)%n+1;if(l>r)std::swap(l,r);
    		for(register int j=Find(l);j<=r;j=Find(j))col[j]=i,fa[j]=j+1;//错误笔记:这里不能写Union(j,j+1),因为这里要保证一定是指向右边的,如果按秩合并就会出问题。 
    	}
    	REP(i,1,n)printf("%d
    ",col[i]);
    }
    
  • 相关阅读:
    SQL中常用的数据类型及简介
    静态方法与非静态方法
    遍历多维数组
    遍历一个三维数组
    冒泡排序-方法2
    关于二分查找分
    冒泡排列-——方法1
    AngularJS 循环查询数组
    AngularJs 指令
    给定一个年月值,返回上个年月值,格式为:YYYY.MM string类型
  • 原文地址:https://www.cnblogs.com/hankeke/p/BZOJ2054.html
Copyright © 2020-2023  润新知