大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华发。人生如梦,一尊还酹江月。

洛谷P3295 [SCOI2016]萌萌哒

倍增加并查集

复杂度 \(O(nlog^2n)\)

虽然AC了,可是一个月后重新看到他还是不会做

直接贴题解

#include<bits/stdc++.h>
using namespace std;

#define go(i,a,b) for(int i=a;i<=b;++i)
#define com(i,a,b) for(int i=a;i>=b;--i)
#define mem(a,b) memset(a,b,sizeof(a))

const int inf=0x3f3f3f3f,N=1e5+10,mod=1e9+7;

int f[N][18],n,m;

inline void read(int &x){
	x=0;char c=getchar(),f=1;
	while(!isdigit(c)){ if(c=='-') f=-1; c=getchar(); }
	while(isdigit(c)){ x=x*10+c-'0'; c=getchar(); }
	x*=f;
}

int find(int x,int i){
	return f[x][i]=f[x][i]==x?x:find(f[x][i],i);
}

void merge(int x,int y,int i){
	x=find(x,i),y=find(y,i);
	if(x==y) return;
	f[y][i]=x;
}

signed main(){
	//freopen("input.txt","r",stdin);
	read(n),read(m);
	int l1,l2,r1,r2;
	const int t=log2(n);
	go(i,1,n)
		go(j,0,t)
			f[i][j]=i;
	go(i,1,m){
		read(l1),read(r1),read(l2),read(r2);
		com(j,t,0){
			if(l1+(1<<j)-1>r1) continue;
			merge(l1,l2,j);
			l1+=1<<j;l2+=1<<j;
		}
	}
	com(k,t,1){
		go(i,1,n-(1<<k)+1){
			int j=find(i,k);
			merge(i,j,k-1);
			merge(i+(1<<k-1),j+(1<<k-1),k-1);
		}
	}
	int ans=0;
	go(i,1,n){
		if(find(i,0)==i) ans=ans==0?9:ans=((long long)ans*10)%mod;
	}
	cout<<ans;
	return 0;
}
posted @ 2019-10-29 15:38  White_star  阅读(106)  评论(0编辑  收藏  举报
}