[BZOJ4569][SCOI2016]萌萌哒
2018-04-02 11:00
363 查看
bzoj
luogu
接着把所有合并标记下方,最后就只要查第\(0\)个并查集里有几个代表元就好了。
luogu
sol
维护\(\log{n}\)个并查集,每个限制就行\(ST\)表那样分成两个区间然后合并。接着把所有合并标记下方,最后就只要查第\(0\)个并查集里有几个代表元就好了。
code
#include<cstdio> #include<algorithm> using namespace std; int gi() { int x=0,w=1;char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if (ch=='-') w=0,ch=getchar(); while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return w?x:-x; } const int N = 2e5+5; const int mod = 1e9+7; int n,m,lg ,ans; struct bcj{ int fa ; void init(){for (int i=1;i<=n;++i) fa[i]=i;} int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} void merge(int i,int j){fa[find(i)]=find(j);} }S[18]; int fastpow(int a,int b) { int res=1; while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;} return res; } int main() { n=gi();m=gi(); for (int i=2;i<=n;++i) lg[i]=lg[i>>1]+1; for (int i=0;i<=lg ;++i) S[i].init(); for (int i=1;i<=m;++i) { int a=gi(),b=gi(),c=gi(),d=gi(),k=lg[b-a+1]; S[k].merge(a,c);S[k].merge(b-(1<<k)+1,d-(1<<k)+1); } for (int j=lg ;j;--j) for (int i=1;i<=n;++i) { int x=S[j].find(i); S[j-1].merge(i,x);S[j-1].merge(i+(1<<j-1),x+(1<<j-1)); } for (int i=1;i<=n;++i) if (S[0].find(i)==i) ++ans; printf("%lld\n",9ll*fastpow(10,ans-1)%mod);return 0; }
相关文章推荐
- [BZOJ 4569][SCOI 2016] 萌萌哒 区间并查集(ST表思想)
- [BZOJ]4569 [SCOI2016] 萌萌哒 并查集神题
- BZOJ 4569: [Scoi2016]萌萌哒 [并查集 倍增]
- BZOJ4569 [Scoi2016]萌萌哒
- 【BZOJ 4569】【SCOI 2016】萌萌哒
- BZOJ 4569 [Scoi2016]萌萌哒
- BZOJ4569 [SCOI2016]萌萌哒 【并查集 + 倍增】
- bzoj4569: [Scoi2016]萌萌哒
- [bzoj4569][SCOI2016]萌萌哒
- BZOJ 4569: [Scoi2016]萌萌哒
- BZOJ 4569: [Scoi2016]萌萌哒
- BZOJ 4569: [Scoi2016]萌萌哒 并查集+倍增
- 【BZOJ4569】[Scoi2016]萌萌哒(并查集+st表)
- BZOJ4569 [Scoi2016]萌萌哒
- bzoj4569 [Scoi2016]萌萌哒 (st表 维护 并查集)
- BZOJ 4569: [Scoi2016]萌萌哒 倍增思维并查集
- BZOJ 4569: [Scoi2016]萌萌哒
- BZOJ 4569: [Scoi2016]萌萌哒 ST表 并查集
- BZOJ 4569 [Scoi2016]萌萌哒 | ST表 并查集
- bzoj 4569: [Scoi2016]萌萌哒