subsets

T1就是个对半搜索裸题……考场上直接A了……没啥好说的……

#include <cstdio>
using namespace std;

const int pps=1e6+7,maxtot=6e4;

int n;
int ans,fake;
bool bo[1<<21];
int val[25],belong[25];

int read() {
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
	return x*f;
}

struct Hash {
	int tot,cnt;
	int head[pps];
	int val[maxtot],nxt[maxtot];
	int now[maxtot],mzf[maxtot*10],pre[maxtot*10];

	void link(int a,int b) {
		pre[++cnt]=now[a];
		now[a]=cnt;mzf[cnt]=b;
	}

	void find(int u,int oxy) {
		for(int p=now[u];p;p=pre[p])
			if(mzf[p]==oxy)return;
		link(u,oxy);
	}

	void add(int v,int oxy) {
		int pos=(v%pps+pps)%pps;
		for(int p=head[pos];p;p=nxt[p])
			if(val[p]==v) {find(p,oxy);return;}
		++tot;val[tot]=v;nxt[tot]=head[pos];head[pos]=tot;
		link(tot,oxy);
	}

	void query(int v,int oxy) {
		int pos=(v%pps+pps)%pps;
		for(int p=head[pos];p;p=nxt[p])
			if(val[p]==v) {
				for(int u=now[p];u;u=pre[u])
					bo[mzf[u]|oxy]=1;
				return;
			}
	}
}H;

void prepare() {
	int res=0,oxy=0;
	for(int i=1;i<=n/2;i++) {
		if(belong[i])oxy|=1<<(i-1);
		if(belong[i]==1)res+=val[i];
		else if(belong[i]==2)res-=val[i];
	}
	H.add(res,oxy);
}

void query() {
	int res=0,oxy=0;
	for(int i=n/2+1;i<=n;i++) {
		if(belong[i])oxy|=1<<(i-1);
		if(belong[i]==1)res-=val[i];
		else if(belong[i]==2)res+=val[i];
	}
	H.query(res,oxy);
}

void dfs_front(int id) {
	if(id==n/2) {prepare();return;}
	for(int i=0;i<3;i++) {
		belong[id+1]=i;
		dfs_front(id+1);
	}
}

void dfs_behind(int id) {
	if(id==n) {query();return;}
	for(int i=0;i<3;i++) {
		belong[id+1]=i;
		dfs_behind(id+1);
	}
}

int main() {
	freopen("subsets.in","r",stdin);
	freopen("subsets.out","w",stdout);
	n=read();
	for(int i=1;i<=n;i++) {
		val[i]=read();
		if(!val[i])fake++;
	}
	dfs_front(0);dfs_behind(n/2);
	for(int s=1;s<1<<n;s++)
		if(bo[s])ans++;
	printf("%d\n",ans-fake);
	return 0;
}

posted on 2018-10-16 19:32  HYSBZ_mzf  阅读(176)  评论(0编辑  收藏  举报

导航