時間限制: 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; }