「題解」:集合論

問題 B: 集合論subset

時間限制: 1 Sec  內存限制: 512 MBc++

題面


題面謝絕公開。算法

題解


貌似能夠直接用數組模擬。數組

不過我當時以爲bitset的&操做能夠完美解決交集問題,徹底忽略了bitset位數對時間複雜度的影響。spa

base:對於插入的每個元素,先加上一個base(有負值)再插入到bitset中。xml

並集:對於插入的每個元素,直接暴力判斷在當前的bitset中存不存在,不存在累加進答案中,並置成存在。blog

交集:先將答案置零,並新建一個bitset。對於插入的每個元素,依舊是暴力強判在bitset中存不存在,不存在就扔掉,存在就累加進答案。ip

對於新建的這個bitset,和本來bitset合併的方式有三種:1.滾動。(最佳選擇)2.賦值。(T85)3.大力相與。(恭喜T飛)。內存

同時加1:兩種選擇:1.bitset總體右移。(恭喜T飛)2.base--。(優秀的算法)get

同時減1與上面相反。it

因此bitset的位運算和位數有關。這種2e6的狀況下仍是很是慢的。

代碼:

#include<bits/stdc++.h>
#define read(A) A=init()
#define rint register int
using namespace std;
char xch,xB[1<<15],*xS(xB),*xTT(xB);
#define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
inline int init()
{
	int x=0,f=1;char ch=getc();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getc();}
	return x*f;
}
int m,siz,wei,opt,sum,ai,extra;
long long ans;
bitset <2000004> bit[2];
main()
{
	read(m);wei=1000000;extra=1000000;
	int now=1;
	for(rint i=1;i<=m;++i)
	{
		read(opt);
		if(opt==1)
		{
			read(sum);
			while(sum--)
			{
				read(ai);
				if(!bit[now][ai+wei])
				{
					ans+=ai,++siz;
					bit[now][ai+wei]=1;
				}
			}
			printf("%lld\n",ans);
		}
		else if(opt==2)
		{
			ans=siz=0;
			read(sum);
			while(sum--)
			{
				read(ai);
				if(bit[now][ai+wei])
				{
					bit[now^1].set(ai+extra);
					ans+=ai,++siz;
				}
			}
			wei=extra;
			bit[now].reset();
			now^=1;
			printf("%lld\n",ans);
		}
		else if(opt==3){--wei;ans+=siz;printf("%lld\n",ans);}
		else{++wei;ans-=siz;printf("%lld\n",ans);}
	}
	return 0;
}
相關文章
相關標籤/搜索