【NC-CT-S02 模拟赛第六场】b

题目

小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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值