[CF1221G] Graph And Numbers

Portal: https://codeforces.com/contest/1221/problem/G

sol:

I feel this title is also very good out of the G ......

First, while there is $ 0 $, $ 1 $, $ 2 $ statistics like the front is not good statistics

That in turn

Total $ 2 ^ n $ Scheme

And then to subtract $ 0 $ no program, no program $ $ 1, $ 2 $ without programs, with no solution $ 0 $, $ 0, $ no program, no program $ 1 $, subtracts no $ 1,2,3 $ program

We discussed separately

Obviously no program of $ 0 and $ 2 $ $ no program number is equivalent to

No $ 0 $ program: consider filling $ 0 $ to $ 1 $, the other is set to $ 0 $, $ 2 ^ {40} $ it seems a little large-scale demolition and a half to find and then determine for the first half of the second half of a certain not choose programs , and then enumerate the second half of the borrowing then we add half of the lawful counting on the line before

No $ 1 $ scheme: i.e., a China Unicom at the same time fill $ 0 or $ 1 $ $ block, block number is provided Unicom $ C $, the answer is $ 2 ^ c $

No $ 0 $ program: that is, only $ 2 $ schemes, this time can be found, in addition to solitary point, the other points are filled $ 1 $, need only count the number of orphans, to $ cnt $, the answer is $ 2 ^ {cnt} $

No $ 0,2 $ program: the program is only $ 1 $, that this time is $ 0101 $ ...... so alternately filled in. If there is an odd ring is not legitimate, if not odd ring, the answer is $ 2 ^ c $, otherwise it is $ 0 $

No $ 2 $ solution: only $ 0 $ program at this time, and only $ 2 $ equivalent scheme

No program $ $ 0,1,2 $ m = 0 $ If the answer is $ 2 ^ n $, $ or $ 0

Probably thinking this way 233

Code may be a bit of trouble

Code:

 

#include <bits/stdc++.h>
using namespace std;
int N,M;
int vis[55];
vector <int> qwq[40];
long long Right[45],cntRight[1<<20];
long long Onl(){ 
    long long ans=0;
    for (int i=0;i<N;i++)
        if (qwq[i].size()==0) ans++;
    return ans;
}
void dfs(int Now,int x){
    if (vis[Now]) return;
    vis[Now]=x;
    for (int i=0;i<qwq[Now].size();i++)
        dfs(qwq[Now][i],3-x);
}
long long GetComponents(){
    memset(vis,0,sizeof(vis));
    long long ans=0;
    for (int i=0;i<N;i++)
        if (!vis[i]){
            ans++;
            dfs(i,1);
        }
    return ans;
}
long long Get02(){
    long long m1=min(N,20);
    long long m2=N-m1;
    memset(cntRight,0,sizeof (cntRight));
    for (long long i=0;i<(1ll<<m1);i++){
        long long Nowmas=0;
        bool flag=true;
            for (int j=0;j<m1;j++){
                if ((i&(1ll<<j))==0) continue;
                    if (Nowmas&(1ll<<j))
                        flag=false;
                    Nowmas|=((1ll<<j)|Right[j]);
            }
        if (flag)
            cntRight[Nowmas>>m1]++;
    }
    for (int i=0;i<m2;i++)
        for (int j=0;j<(1<<m2);j++)
            if (j&(1ll<<i))
                cntRight[j]+=cntRight[j^(1ll<<i)];
    long long ans=0;
    for (long long i=0;i<(1<<m2);i++){
        long long Nowmas=0;
        bool flag=true;
        for (int j=m1;j<N;j++){
            if ((i&(1<<(j-m1)))==0) continue;
                if (Nowmas&(1ll<<j))
                    flag=false;
            Nowmas|=(1ll<<j)|Right[j];    
        }
        if (flag) 
            ans += cntRight[i^((1ll<<m2)-1)];
    }
    return ans;
}
bool Non_Odd(){
    memset(vis,0,sizeof(vis));
    for (int i=0;i<N;i++)
        if (!vis[i])
            dfs(i,1);
    for (int i=0;i<N;i++){
            for (int j=0;j<qwq[i].size();j++)
                if (vis[i]==vis[qwq[i][j]]) return false;
    }
    return true;
}
long long Pow(long long x,long long y){
    long long ans=1;
    for (;y;y>>=1){
        if (y&1) ans=ans*x;
        x=x*x;
    }
    return ans;
}
long long Calc(int Mask){
    if (Mask==0) return Pow(2,N);
    if (Mask==1||Mask==4) {return Get02();}
    if (Mask==2){return Pow(2,GetComponents());}
    if (Mask==3||Mask==6){return Pow(2,Onl());}
    if (Mask==5){if (Non_Odd()) return Pow(2,GetComponents());else return 0;}
    if (Mask==7) {if (M==0) return Pow(2,N);else return 0;}
}
int main(){
    scanf("%d%d",&N,&M);
    for (int i=0;i<M;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        --x;--y;
        qwq[x].push_back(y);
        qwq[y].push_back(x); 
        Right[x]^=(1ll<<y);
        Right[y]^=(1ll<<x);
    }
    long long ans=0;
    for (int i=0;i<8;i++){
        if (__builtin_popcount(i)%2==0)
            ans+=Calc (i);
        elseans- = Calc (i); 
    } 
    Cout << years;
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/si--nian/p/11594457.html