[考试反思]0409省选模拟66:大顺

原来大顺指的是暴力能拿高分啊

$T1$的$3^n$过了$19$。$T2$的$2^n n^2$过了$22$。$T3$听他们说$n^3logn$过了$2000$

(虽说我复杂度和他们是一样的但我就没过去。。。)

$T1$是原题强化,然而并不会子集卷积,打了个暴力跑路。

$T2$大概猜到了状态数很少但是并不知道原来搜索真的可以过,写了个状压(数组开大)多拿了$5$分。

$T3$的想法其实大概擦到了$60pts$的边但并没有想下去。暴力跑路。

没想到这次三暴力并不差。

T1:有限空间跳跃理论

大意:图边定向后是$DAG$的方案数。$n \le 20$

被$LNC$疯狂嘲讽。

$dp_{i|j}=\sum\limits_{i \cap j = 0}dp_i + rate_j$

$rate_j=[j内部无边](-1)^{popcnt(j)-1}$

子集卷积并卡常。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mod 1000000007
 4 int n,m,e[22],dp[23][1<<21],bit[1<<21],ok[22][1<<21];
 5 int add(int&a,int b){a+=b;if(a>=mod)a-=mod;}
 6 void FWT(int*a){for(int i=0;i<n;++i)for(int j=0;j<1<<n;++j)if(j&1<<i)add(a[j],a[j^1<<i]);}
 7 void IFWT(int*a){for(int i=0;i<n;++i)for(int j=0;j<1<<n;++j)if(j&1<<i)add(a[j],mod-a[j^1<<i]);}
 8 int main(){
 9     cin>>n>>m;
10     for(int a,b,i=1;i<=m;++i)scanf("%d%d",&a,&b),e[a-1]|=1<<b-1,e[b-1]|=1<<a-1;
11     for(int i=1;i<1<<n;++i)bit[i]=bit[i^i&-i]+1;
12     for(int i=1;i<1<<n;++i){
13         ok[bit[i]][i]=bit[i]&1?1:mod-1;
14         for(int j=0;j<n;++j)if(i>>j&1&&e[j]&i)ok[bit[i]][i]=0;
15     }
16     for(int i=1;i<=n;++i)FWT(ok[i]);
17     dp[0][0]=1; FWT(dp[0]);
18     for(int i=0;i<n;++i)for(int j=1;i+j<=n;++j)for(int x=0;x<1<<n;++x)if(dp[i][x]&&ok[j][x])
19         dp[i+j][x]=(dp[i+j][x]+1ll*dp[i][x]*ok[j][x])%mod;
20     IFWT(dp[n]);
21     cout<<dp[n][(1<<n)-1];
22 }
View Code

T2:神秘代码

大意:给定$01$串$s$求有多少排列$a$满足$s_i=1$则$a_i=2a_{i-1}$或$a_{i-1}=2a_i$。若$s_i=0$则满足$a_i\neq 2a_{i-1}$且$a_{i-1}\neq 2a_i,n \le 40$

可以发现$2$倍关系构成若干链。然后每次要求取出一段特定长度的链,然后下一个位置上$ban$掉零或一或二种数。

记搜,状态压一下长度为$1,2,3,4,5,6$的链各还有几个以及$ban$掉的链的长度即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mod 1000000007
 4 int cnt[7],nd[66],n,d;char c[66];
 5 struct hash_map{
 6     #define S 235711
 7     int fir[S],l[S],v[S],ec,to[S];
 8     int&operator[](int x){int r=x%S;
 9         for(int i=fir[r];i;i=l[i])if(to[i]==x)return v[i];
10         l[++ec]=fir[r];fir[r]=ec;to[ec]=x;return v[ec]=-1;
11     }
12 }M[66];
13 int sch(int o,int x,int y){//cerr<<o<<' '<<cnt[1]<<' '<<cnt[2]<<' '<<cnt[3]<<endl;
14     if(o==d+1)return 1;
15     int&ans=M[o][cnt[6]<<29|cnt[5]<<26|cnt[4]<<22|cnt[3]<<17|cnt[2]<<12|cnt[1]<<6|x<<3|y],r;
16     #define I i-j-nd[o]
17     if(ans!=-1)return ans; ans=0;
18     if(nd[o]==1){
19         for(int i=1;i<=6;++i)for(int j=0;j<i;++j)if(r=cnt[i]-(x==i&&!j)-(y==i&&!j))
20             cnt[i]--,cnt[j]++,cnt[I]++,ans=(ans+1ll*r*sch(o+1,j,I))%mod,cnt[i]++,cnt[j]--,cnt[I]--;
21     }else for(int i=nd[o];i<=6;++i)for(int j=0;j+nd[o]<=i;++j)if(r=cnt[i])
22         cnt[i]--,cnt[j]++,cnt[I]++,ans=(ans+1ll*r*sch(o+1,j,0)+1ll*(r-(x==i&&!j)-(y==i&&!j))*sch(o+1,I,0))%mod,cnt[i]++,cnt[j]--,cnt[I]--;
23     return ans;
24 }
25 int main(){//freopen("code8.in","r",stdin);
26     cin>>n>>c+1;
27     if(c[1]=='0')nd[d=1]=1;
28     for(int i=1;i<n;++i){
29         if(nd[d]==1&&c[i]=='1')d--; d++;nd[d]=1;
30         while(c[i]=='1')i++,nd[d]++;
31         if(c[i]=='0'&&nd[d]!=1)nd[++d]=1;
32     }//for(int i=1;i<=d;++i)cerr<<nd[i]<<' ';cerr<<endl;
33     for(int j=n/2+1;j<=n;++j){
34         int r=j,c=1;
35         while(!(r&1))r>>=1,c++;
36         cnt[c]++;
37     }cout<<sch(1,0,0)<<endl;
38 }
View Code

T3:预言

鸽了。牛爷爷怎么什么都会啊。

猜你喜欢

转载自www.cnblogs.com/hzoi-DeepinC/p/12670979.html
今日推荐