图论+思维(2019牛客国庆集训派对day2)

时间:2021-03-12 14:55:45

题意:https://ac.nowcoder.com/acm/contest/1107/J

n个点的完全图编号0-n-1,第i个点的权值为2^i,原先是先手选取一些边,然后后手选取一些点,满足先手选取的所有边对应的两点至少要有一个,并且总的权值和最少,现在给你后手选取的点得权值和,求先手选取边的方案数(就是先手选取完一些边,要求后手选一些点使所有边都被覆盖到并且权值和最小,现在告诉你后手的权值和问你先手的取法方案数)

思路:

因为权值是二进制的形式给的,所以对应1的位置即对应的这个点也选了,对于选取的点来说,一定要和比他权值更大的点并且是没有被选择的点相连接,这样这个点才必须选择,和比他权值小的点可连可不连。https://blog.csdn.net/mmk27_word/article/details/90670209

 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>//freopen("C:\\Users\\13606\\Desktop\\草稿.txt","r",stdin);
#include <bitset>
//#include <map>
//#include<unordered_map>
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr
#include <string>
#include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
//******************
int abss(int a);
int lowbit(int n);
int Del_bit_1(int n);
int maxx(int a,int b);
int minn(int a,int b);
double fabss(double a);
void swapp(int &a,int &b);
clock_t __STRAT,__END;
double __TOTALTIME;
void _MS(){__STRAT=clock();}
void _ME(){__END=clock();__TOTALTIME=(double)(__END-__STRAT)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
//***********************
#define rint register int
#define fo(a,b,c) for(rint a=b;a<=c;++a)
#define fr(a,b,c) for(rint a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
typedef long long ll;
const double E=2.718281828;
const double PI=acos(-1.0);
//const ll INF=(1LL<<60);
const int inf=(<<);
const double ESP=1e-;
const int mod=(int)1e9+;
const int N=(int)1e6+; char temp[N],k[N];
ll dp[N],er[N]; ll get(int pos,int n)
{
ll ans=;
ans=ans*((er[dp[pos]]-+mod)%mod)%mod*er[n-pos]%mod;
return ans;
} int main()
{
int n;
er[]=;
er[]=;
for(int i=;i<=N-;++i)
er[i]=er[i-]*,er[i]%=mod;
while(~sc("%d%s",&n,temp+))
{
int l=strlen(temp+);
int cnt=n-l;
for(int i=;i<=cnt;++i)
k[i]='';
for(int i=;i<=l;++i)
k[i+cnt]=temp[i];
l=cnt+l;
for(int i=;i<=l;++i)
{
dp[i]=dp[i-];
if(k[i]=='')
dp[i]++;
}
ll ans=;
for(int i=;i<=l;++i)
{
if(k[i]=='')continue;
ans*=get(i,l);
ans%=mod;
}
pr("%lld\n",ans);
}
return ;
} /**************************************************************************************/ int maxx(int a,int b)
{
return a>b?a:b;
} void swapp(int &a,int &b)
{
a^=b^=a^=b;
} int lowbit(int n)
{
return n&(-n);
} int Del_bit_1(int n)
{
return n&(n-);
} int abss(int a)
{
return a>?a:-a;
} double fabss(double a)
{
return a>?a:-a;
} int minn(int a,int b)
{
return a<b?a:b;
}