题目
小z最近又迷上了一个推球的游戏。在数轴上点 a1,a2,…,ama1,a2,…,am 各有一个球,在点 b1+0.5,b2+0.5,…,bl+0.5b1+0.5,b2+0.5,…,bl+0.5 的地方各有一个洞,小z会把球全部向正方向推,直到落入一个洞中,一个洞能容纳无穷多的球。小z认为这样一次游戏的得分是最终有球的洞的数量,记为 score({a1,a2,…,am},{b1,b2,…,bl})score({a1,a2,…,am},{b1,b2,…,bl}) 现在小 z 有 n 个集合 S1,S2,…,SnS1,S2,…,Sn,小z想知道 ⨁1≤i<j≤ni×j×score(Si,Sj)⨁1≤i<j≤ni×j×score(Si,Sj) 。其中 ⨁⨁ 表示按位异或。
输入格式
第一行一个整数 nn。
接下来 nn 行,每行表示一个集合,第一个整数 kiki,表示集合大小。接下来 kiki 个整数,SijSij.
输出格式
一行一个整数表示答案。
样例数据
输入样例一
2
2 1 2
2 2 1
输出样例一
4
数据规模与约定
对于 20% 的数据满足,1≤ki,Si,j≤101≤ki,Si,j≤10
对于 60% 的数据满足,1≤ki,Si,j≤501≤ki,Si,j≤50
对于 100% 的数据满足,1≤n≤5000,1≤ki,Si,j≤5001≤n≤5000,1≤ki,Si,j≤500。
时间限制:3s3s
空间限制:512MB
思路
对球 ai,找最小的 j 使得洞 bj ≥ ai
hole&(ball+(~hole))
bitset
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAX_L=505;
const int MAX_N=5005;
const int bitmask=(1LL<<32)-1;
struct Bitset{
unsigned int s[16];
Bitset(){for(char i=0;i<16;++i)s[i]=0;}
void set(int x){
s[x>>5]|=1<<(x&31);
}
inline Bitset operator&(const Bitset &x)const{
Bitset ans;
for(char i=0;i<16;++i)ans.s[i]=s[i]&x.s[i];
return ans;
}
inline Bitset operator|(const Bitset &x)const{
Bitset ans;
for(char i=0;i<16;++i)ans.s[i]=s[i]|x.s[i];
return ans;
}
inline Bitset operator^(const Bitset &x)const{
Bitset ans;
for(char i=0;i<16;++i)ans.s[i]=s[i]^x.s[i];
return ans;
}
inline Bitset operator~()const{
Bitset ans;
for(char i=0;i<16;++i)ans.s[i]=~s[i];
return ans;
}
inline Bitset operator+(const Bitset &x)const{
Bitset ans;
unsigned int w=0;LL t;
for(char i=0;i<16;++i){
t=(LL)x.s[i]+s[i]+w;
ans.s[i]=t&((1ll<<32)-1);
w=t>>32;
}
return ans;
}
inline int count(){
int ans=0;
for(char i=0;i<16;++i)ans+=__builtin_popcount(s[i]);
return ans;
}
};
Bitset bit[MAX_N];
int n;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
{
int siz;
cin>>siz;
for(int j=1;j<=siz;j++)
{
int x;
cin>>x;
bit[i].set(x-1);
}
}
LL ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
Bitset bit1=bit[i],bit2=bit[j];
Bitset bit3=bit1&bit2;
bit1=bit1 xor bit3;
bit3=bit3|(bit2&(bit1+(~bit2)));
ans=ans xor (1ll*i*j*bit3.count());
}
}
cout<<ans<<endl;
return 0;
}