牛客多校第七场C Bit Compression

考场上直接就想到处理最后2^4=16位,然后去爆搜,然而,当时觉得第一层要遍历所有数字,2^18,第二层2^17,跟本不敢写,以为复杂度趋近与2^18*3^10+左右,然而事实上。最后算出来竟然8*1e8,那我们再对最后16位搞个状压数字再记忆化一蛤,之后就只有2*1e8,我感觉常数一大还是不行,然而,我也不知道为撒只跑了400ms,那些没写记忆化的人,有些1000+ms也过了,没想到是一道暴力水题。。。我也是服了,以后还是要认真算一下复杂度。。。

#include<cstdio>
#include<cstring>
#define maxl 362145

int n;
int to[maxl][4];
int len[maxl];
int a[20][maxl]; 
long long ans;
long long dp[5][maxl];
bool vis[5][maxl];
char s[maxl];
bool in[maxl];

inline void prework()
{
	scanf("%s",s+1);
	for(int i=1;i<=(1<<n);i++)
		a[n][i]=s[i]-'0';
}

inline long long dfs(int k)
{
	int num;
	long long sum=0;
	if(k<=4)
	{
		num=0;
		for(int i=1;i<=(1<<k);i++)
			num=(num<<1)+a[k][i];
		if(vis[k][num])
			return dp[k][num];
		for(int i=1;i<=(1<<(k-1));i++)
			a[k-1][i]=a[k][(i<<1)-1]&a[k][i<<1];
		sum+=dfs(k-1);
		for(int i=1;i<=(1<<(k-1));i++)
			a[k-1][i]=a[k][(i<<1)-1]|a[k][i<<1];
		sum+=dfs(k-1);
		for(int i=1;i<=(1<<(k-1));i++)
			a[k-1][i]=a[k][(i<<1)-1]^a[k][i<<1];
		sum+=dfs(k-1);
		vis[k][num]=true;dp[k][num]=sum;
		return sum;
	}
	for(int i=1;i<=(1<<k);i++)
		num=(num<<1)+a[k][i];
	for(int i=1;i<=(1<<(k-1));i++)
		a[k-1][i]=a[k][(i<<1)-1]&a[k][i<<1];
	sum+=dfs(k-1);
	
	for(int i=1;i<=(1<<(k-1));i++)
		a[k-1][i]=a[k][(i<<1)-1]|a[k][i<<1];
	sum+=dfs(k-1);
	
	for(int i=1;i<=(1<<(k-1));i++)
		a[k-1][i]=a[k][(i<<1)-1]^a[k][i<<1];
	sum+=dfs(k-1);
	
	return sum;
}

inline void mainwork()
{
	ans=0;
	dp[0][1]=1;vis[0][1]=true;dp[0][0]=0;vis[0][0]=true;
	ans=dfs(n);
}

inline void print()
{
	printf("%lld\n",ans);
}

int main()
{
	while(~scanf("%d",&n))
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/81557348