[容斥] Topcoder SRM div1-3 12004. SetAndSet
2017-10-31 17:19
363 查看
把所有数取反,转换成分成两个集合,集合或值相同。
容斥一下
每次枚举哪些位不满足条件,用并查集维护一下要在同一个集合的联通块就好了
容斥一下
每次枚举哪些位不满足条件,用并查集维护一下要在同一个集合的联通块就好了
#include <cstdio> #include <iostream> #include <algorithm> #include <vector> #include <cstring> using namespace std; class SetAndSet{ public: typedef long long ll; vector<int> b[25]; int n,f[55],a[25],vis[55]; ll ans; int Gfat(int x){ return f[x]==x?x:f[x]=Gfat(f[x]); } void dfs(int x,int y){ if(x>=20){ int cnt=0; for(int i=1;i<=n;i++) vis[i]=0; for(int i=1;i<=n;i++){ if(!vis[Gfat(i)]) cnt++,vis[Gfat(i)]=1; } if(y&1) ans-=(1LL<<cnt)-2; else ans+=(1LL<<cnt)-2; return ; } dfs(x+1,y); if(b[x].size()<1) return ; int curf[55]; memcpy(curf,f,sizeof(curf)); // for(int i=1;i<=n;i++) curf[i]=f[i]; int nf=Gfat(b[x][0]); for(int j=1;j<b[x].size();j++) f[Gfat(b[x][j])]=nf; dfs(x+1,y+1); memcpy(f,curf,sizeof(f)); // for(int i=1;i<=n;i++) f[i]=curf[i]; } ll countandset(vector<int> A){ n=A.size(); ans=0; for(int i=1;i<=n;i++) f[i]=i; for(int i=0;i<n;i++) for(int j=0;j<20;j++) if(~A[i]>>j&1) b[j].push_back(i+1); dfs(0,0); for(int i=0;i<20;i++) b[i].clear(); return ans; } }; inline void run_(int test_){ vector<int> a; SetAndSet A; if(test_==0){ a.push_back(1); a.push_back(2); cout<<A.countandset(a)<<endl; } if(test_==1){ a.push_back(1); a.push_back(2); a.push_back(3); a.push_back(4); cout<<A.countandset(a)<<endl;} if(test_==2){ for(int i=1;i<=5;i++) a.push_back(i); cout<<A.countandset(a)<<endl; } if(test_==3){ for(int i=1;i<=3;i++) a.push_back(6); cout<<A.countandset(a)<<endl; } if(test_==4){ a.push_back(13); a.push_back(10); a.push_back(4); a.push_back(15); a.push_back(4); a.push_back(8); a.push_back(4); a.push_back(2); a.push_back(4); a.push_back(14); a.push_back(0); cout<<A.countandset(a)<<endl;} if(test_==5){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); int n;scanf("%d",&n); for(int i=1,x;i<=n;i++) scanf("%d",&x),a.push_back(x); cout<<A.countandset(a)<<endl; } }
相关文章推荐
- TopCoder SRM 668 Div2 Problem 1000 - AnArray (数学)
- topcoder srm 518 div 2
- TopCoder SRM 649 Div2 Problem 500 - CartInSupermarketEasy (区间DP)
- Topcoder SRM 573 WolfPackDivTwo
- topcoder srm 519 div 1
- topcoder SRM588 DIV1 解题报告
- TopCoder SRM 681 Div. 2 Problem 500 - ExplodingRobots (枚举)
- TopCoder Practice SRMs -- SRM 144 DIV 1 -- 300p
- TopCoder SRM144 DIV1(one)
- topcoder SRM div 2 level 1
- topcoder srm 682 div1 -3
- Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串
- Topcoder SRM 668 DIV 2
- Topcoder SRM 688 div2
- Topcoder SRM 656 DIV2 1000 题解(动态规划)
- TopCoder SRM 659 Div2 Problem 500 - PublicTransit (思维)
- TOPCODER/SRM 566 DIVII(250、500、1000题)(1000PT暂未附上代码)
- topcoder SRM495 div1 level3
- Top Coder SRM 614 DIV 2
- SetAndSet(SRM545-div1-3)