[BZOJ4569] [Scoi2016] pyridazin Mengmeng
Good question!
Doubling the maintenance and check collection and
A multiplier array \ (fa [i] [j ] \) from the maintenance \ (I \) begins length \ (2 ^ j \) in this section and that section of the same length and together
The section ends \ (l1, r2, l2, r2 \) by multiplying cut open, and check with the layer set in the multiplier array and
Finally, each time \ (fa [i] [j ] \) to \ (fa [i] [j -1], fa [i + (1 << (j-1))] [j-1] \) Delivery can push
int n,m;
struct UFS{
int fa[N];
int Find(int x) { return fa[x]==x?x:fa[x]=Find(fa[x]); }
void init(){ rep(i,1,n) fa[i]=i; }
void merge(int x,int y) {
fa[Find(x)]=Find(y);
}
} B[18];
int LOG;
int main(){
n=rd(),m=rd();
for(LOG=0;(1<<LOG)<=n;LOG++) B[LOG].init();
LOG--;
rep(i,1,m) {
int l1=rd(),r1=rd();
int l2=rd();rd();
if(l1==l2) continue;
int len=r1-l1+1;
drep(j,LOG,0) {
if(len>=(1<<j)) {
B[j].merge(l1,l2);
l1+=1<<j,l2+=1<<j;
len-=1<<j;
}
}
}
drep(i,LOG,1) {
int len=(1<<(i-1));
rep(j,1,n) {
int f=B[i].Find(j);
B[i-1].merge(j,f);
B[i-1].merge(j+len,f+len);
}
}
int cnt=0;
rep(i,1,n) if(B[0].Find(i)==i) cnt++;
ll ans=1;
rep(i,1,cnt-1) ans=ans*10%P;
ans=ans*9%P;
printf("%lld\n",ans);
}