SCOI2016 Meng Meng da solution to a problem

SCOI2016 Meng Meng da solution to a problem

Topic Link


 

Thinking

This topic probably give you some restrictions, so that the interval is equal, then a very clever idea is to limit the interval into two shops in a disjoint-set in

We ask only one of a number of disjoint-set, the answer is (t All we ask is only one number and check the set) 

But direct manipulation through the large complex

thenSomeoneThink of doubling

f[i][j]Representing the interval [  ,  ] where the disjoint-set

Record each major section of the very beginning about his son

Enter  l1 l2 r1 r2merge the same time as the ST table

 

Re-processes each large intervals, if f[i][j]and f[a][b]in a disjoint-set in, their son is also about a disjoint-set, we will be able to pass around his son's large range of information merge merge (left son and left son merger, the son of the right son with the right consolidation)

Final tally f[i][0]of the number of disjoint-set to

 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define re register int
#define ll long long
#define MN 1000050
#define mod 1000000007
using namespace std;
int bcj[MN*22],f[MN][22],lc[MN*22],rc[MN*22],lg[MN];
int n,m,k,ltk,cnt;
int find(int x){
    if(x==bcj[x])return x;
    bcj[x]=find(bcj[x]);
    return bcj[x];
}
void merge(int x,int y){
    int t1=find(x),t2=find(y);
    if(t1!=t2)bcj[t2]=t1;
}
int main(){
    scanf("%d%d",&n,&m);
    for(re i=2;i<=n;i++)
        lg[i]=lg[i/2]+1;    
    for(re j=lg[n];j>=0;j--)
        for(re i=1;i+(. 1 << J) - . 1 <= n-; I ++ ) { 
                F [I] [J] = ++ CNT; 
                BCJ [CNT] = CNT; 
        } // to a large range of numbers 
    for (J = Re . 1 ; J <= LG [n-]; J ++ )
         for (Re I = . 1 ; I + ( . 1 << J) - . 1 <= n-; I ++ ) { 
            LC [F [I] [J]] = F [I] [J- . 1 ] ; 
            RC [F [I] [J]] = F [I + ( . 1 << (J- . 1 ))] [J- . 1 ]; 
        } // statistics about son 
    for (I = Re1;i<=m;i++){
        int a1,a2,a3,a4;
        scanf("%d%d%d%d",&a1,&a2,&a3,&a4);
        int l=lg[a2-a1+1];
        merge(f[a1][l],f[a3][l]);
        merge(f[a2-(1<<l)+1][l],f[a4-(1<<l)+1][l]);
    }//像st表一样合并
    for(re i=1;i<=cnt;i++){
        if(!lc[i]||!rc[i])continue;
        int t1=find(i);
        if(T1 =! I) { 
            Merge (LC [T1], LC [I]); 
            Merge (RC [T1], RC [I]); 
            // if f [i] [j] and f [a] [b ] belong to a link block, they belong to a left and right son Unicom block 
        } 
    } 
    LTK = n-;
     // assume the position of each block is independent Unicom, if Unicom minus 
    for (I = Re . 1 ; I <= n- ; I ++ ) {
         IF (Find (F [I] [ 0 ]) = F [I] [! 0 ]) 
            LTK - ; 
    } 
    LL ANS = . 9 ;
     for (Re I = . 1 ; I <LTK; I ++ ) 
        ANS = (ANS% MOD * 10 )%mod;
        printf("%lld",ans%mod);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/zw130-lzr-blogs/p/11274501.html