2018 K Ningxia Invitational title Vertex Covers (high-dimensional binary prefixes and shaped pressure

https://vjudge.net/problem/Gym-102222K

The meaning of problems: None given to N-point M of FIG edges, a little right of each point. Coverage point represents a point set S {} covers all of the sides, which contribution is the product of the midpoint of the right of S. Now let's ask you all to meet the conditions of point set sum of the contributions. N <36, to ensure that no edge weight, loopback.

Ideas: finding out not sure whom to cover the point-like pressure, N 36 again a binary, and then find a way to merge two sides. Can enumerate the left side of the pile point status, for those not selected point on the left, the other left point if he connects have been selected (otherwise the state rounding),

He determined that the right connection point, i.e. is mandatory right point, then the right can be selected from the set of points or a mandatory superset, first to the right of each pretreatment state.

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2000010;
int a[maxn],sum[maxn],ltl[40],ltr[40],rtr[40],Mod;
void MOD(int &x){ if(x>=Mod) x-=Mod;}

int main(){
    int T,N,M,u,v,C=0;
    cin>>T;
    while(T--){
        cin>>N>>M>>Mod;
        rep(i,0,N-1) cin>>a[i];
        rep(i,0,N-1) ltl[i]=ltr[i]=rtr[i]=0;
        int L=(N+1)/2,R=N-L,ans=0;
        rep(i,1,M){
            cin>>u>>v;
            u--,v--;
            if(u>v) swap(u,v);
            if(u<L){
                if(v<L) ltl[u] |= (1<<v);
                else ltr[u] |= (1<<(v-L));
            }
            else rtr[u] |= (1<<(v-L));
        }
        rep(i,0,(1<<R)-1){
            int res = 1;
            rep(j,0,R-1){
                if(i&(1<<j)) res = 1LL*res*a[j+L]%Mod;
                else{
                    res = res*((rtr[j+L]|i)==i);
                    if(!res) break;
                }
            }
            sum[i] = res;
        }
        rep(i,0,R-1){
            rep(j,0,(1<<R)-1){
                if(!(j&(1<<i))) MOD(sum[j]+=sum[j|(1<<i)]);
            }
        }
        rep(i,0,(1<<L)-1){
            int res=1,need=0;
            rep(j,0,L-1){
                if(i&(1<<j)) res = 1LL*res*a[j]%Mod;
                else{
                    res = res*((ltl[j]|i)==i),need|=ltr[j];
                    if(!res) break;
                }
            }
            MOD(ans+=1LL*res*sum[need]%Mod);
        }
        printf("Case #%d: %d\n",++C,ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/wzgg/p/11457453.html