19-11-10-Night

关于$Miemeng$,它死了。

大家有没有记得我在暑假里曾经写过一个著名模数?

const int Mod=998224353;

现在有续集了(捂脸)(改不过题.jpg)

const int Mod=988244353;

ZJ:

我对不起大家我又咕咕咕了,话说为什么我挂起的电脑……

T1Adore,看起来很熟悉……不知道是什么时候见过这个词……

于是发现不可做。打一个暴力就丢了。

T2发现暴力很好打,先码了一个,先rand了几个数据,发现答案大都是$1\ 2$

emm,本来想一边输入一边扫,但是后来弃掉了(为什么要弃啊啊啊?

T3发现很贪心,但是只会输出$n$(滑稽

(后来听说输出$\frac{n}{s}$有$50$)

39
Miemeng 0
00:00:03
50
00:00:04
20
00:00:05
70
00:00:05

啊T1为什么爆〇了????

TJ:

T1

状压即可,设$f_{i,s}$为第$i$层点权奇偶性为$s$(奇为$1$,偶为$0$)时前$i$层的方案数

于是预处理取反边,并且直接转移就好了。

最后的答案就是$f_{n,0}$

复杂度$\Theta(NK 2^K)$

#include <iostream>
#include <cstring>
#include <cstdio>

//#include "debug.h"

#define N 11111
#define K 12
#define S (1<<K)+111
#define LL long long
using namespace std;

const int Mod=998244353;
int cn,pn;
LL dp[N][S];
int mp[N][K],pm[N][K];
int dat[N][K][K];

void prerun(){
	for(int i=1;i<=pn;i++){
		mp[1][1] |= dat[1][1][i]<<(i-1);
	}
	for(int i=2;i<cn-1;i++){
		for(int j=1;j<=pn;j++){
			for(int k=1;k<=pn;k++){
				mp[i][j] |= dat[i][j][k]<<(k-1);
				pm[i][k] |= dat[i][j][k]<<(j-1);
			}
		}
	}
	for(int i=1;i<=pn;i++){
		mp[cn-1][i] |= dat[cn-1][i][1];
//		cout<<mp[cn-1][i]<<" ";
	}
//	cout<<endl;
}
int main(){
#ifndef LOCAL
	freopen("adore.in" ,"r",stdin);
	freopen("adore.out","w",stdout);
#endif
	scanf("%d%d",&cn,&pn);
	for(int i=1;i<=pn;i++){
		scanf("%d",&dat[1][1][i]);
	}
	for(int i=2;i<cn-1;i++){
		for(int j=1;j<=pn;j++){
			for(int k=1;k<=pn;k++){
				scanf("%d",&dat[i][j][k]);
			}
		}
	}
	for(int i=1;i<=pn;i++){
		scanf("%d",&dat[cn-1][i][1]);
	}
	prerun();
/*	for(int i=1;i<=cn;i++){
		for(int j=1;j<=pn;j++){
			cout<<i<<" "<<j<<" "<<bin(mp[i][j],pn)<<endl;
		}
	}*/
	dp[2][mp[1][1]]=1;
	for(int i=2;i<cn-1;i++){
		for(int s=0;s<1<<pn;s++){
//			cout<<"dp["<<i<<"]["<<bin(s,pn)<<"]="<<dp[i][s]<<endl;
			int pos=0,sop=0;
			for(int j=1;j<=pn;j++){
				int k=1<<(j-1);
				if(k&s){
					pos^=mp[i][j];
					sop^=pm[i][j];
				}
			}
			dp[i+1][pos]+=dp[i][s];
			dp[i+1][pos]%=Mod;
			dp[i+1][sop]+=dp[i][s];
			dp[i+1][sop]%=Mod;
		}
	}
	for(int s=0;s<1<<pn;s++){
		int pos=0;
//		cout<<"dp["<<cn-1<<"]["<<bin(s,pn)<<"]="<<dp[cn-1][s]<<endl;
		for(int i=1;i<=pn;i++){
			int j=1<<(i-1);
			if(j&s){
				pos^=mp[cn-1][i];
//				cout<<"pos:"<<bin(pos,pn)<<"<-"<<j<<" "<<mp[cn-1][j]<<endl;
			}
		}
		dp[cn][pos]+=dp[cn-1][s];
		dp[cn][pos]%=Mod;
	}
	printf("%lld\n",dp[cn][0]);
}

T2:

考试的小剪枝暴力tong过本题。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <bitset>
#define N 6666
using namespace std;

int sn;
char str[N*100];
bitset <2*N> vals[N];
int main(){
#ifndef LOCAL
	freopen("confess.in" ,"r",stdin);
	freopen("confess.out","w",stdout);
#endif
	scanf("%d",&sn);
	for(int i=1;i<=sn+1;i++){
		int cnt=0;
		scanf("%s",str);
		int len=strlen(str);
		for(int j=0;j<len;j++){
			int dat=str[j]-33;
			for(int k=0;k<6;k++){
				vals[i]<<=1;
				cnt++;
				vals[i].set(0,dat>>k&1);
				if(cnt==2*sn)goto nxtt;
			}
		}
		nxtt:;
		for(int j=1;j<i;j++){
			if((int)(vals[i]&vals[j]).count()>=sn/2){
				cout<<i<<" "<<j<<endl;
				return 0;
			}
		}
	}
}

但是正解是随机化……

(随机化可过的题大多都可以暴力剪枝过……)

T3咕掉了,也不想粘题解。

posted @ 2019-11-11 07:22  Miemeng_麦蒙  阅读(232)  评论(0编辑  收藏  举报

小麦在雨中,蒙蒙的雾气

麦蒙不想有人骚扰他,如果有必要 联系 QQ:1755601414

如果你嫌广告大,那就喷我吧,不是博客园的锅。