首页 > 代码库 > ural 1932 The Secret of Identifier 容斥

ural 1932 The Secret of Identifier 容斥

题目链接:点击打开链接

stl+容斥

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <set>
using namespace std;
#define N 65540
#define ll __int64
ll n;
ll a[N][4], mul[4]={1,16,256,4096};
ll h[N];
vector<ll>G[N];
set<ll>myset;
set<ll>::iterator p;
ll find1(ll x){ //设除了x位,其他3位相同
	myset.clear();
	for(ll i = 0; i < n; i++){
		ll now = 0;
		for(ll j = 0; j < 4; j++)if(j!=x)
		now += a[i][j];
		G[now].push_back(i);
		myset.insert(now);
	}
	ll ans = 0;
	for(p = myset.begin(); p!=myset.end(); p++) {
		ll siz = G[*p].size();
		ans += (siz*(siz-1))>>1;
		G[*p].clear();
	}
	return ans;
}

ll find2(ll x,ll y){
	myset.clear();
	for(ll i = 0; i < n; i++) {
		ll now = 0;
		for(ll j = 0; j < 4; j++)if(j!=x&&j!=y)
			now += a[i][j];
		G[now].push_back(i);
		myset.insert(now);
	}
	ll ans = 0;
	for(p = myset.begin(); p!=myset.end(); p++) {
		ll siz = G[*p].size();
		ans += (siz*(siz-1))>>1;
		G[*p].clear();
	}
	return ans;
}
ll find3(ll x){
	myset.clear();
	for(ll i = 0; i < n; i++){
		ll now = 0;
		now += a[i][x];
		G[now].push_back(i);
		myset.insert(now);
	}
	ll ans = 0;
	for(p = myset.begin(); p!=myset.end(); p++) {
		ll siz = G[*p].size();
		ans += (siz*(siz-1))>>1;
		G[*p].clear();
	}
	return ans;
}
int main(){
	ll i,j;
	for(ll i = 0; i < N; i++)G[i].clear();
	while(cin>>n) {
		for(i=0;i<n;i++)
		{
			char s[10]; scanf("%s",s);
			for(j=0;j<4;j++) {
				a[i][j] = ('0'<=s[j]&&s[j]<='9')?s[j]-'0':s[j]-'a'+10;
				a[i][j] *= mul[j];
			}
		}
		ll ans[5] = {0};
		ans[1] = find1(0) + find1(1) + find1(2) + find1(3);
		ans[2] = find2(0,1) + find2(0,2) + find2(0,3) + find2(1,2) + find2(1,3) + find2(2,3) - ans[1]*3;
		ans[3] = find3(0) + find3(1) + find3(2) + find3(3) - ans[1]*3 - ans[2]*2;
		ll all = (ll) ((n*(n-1))/2);
		ans[4] = all - ans[1] - ans[2] - ans[3];
		cout<<ans[1]<<" "<<ans[2]<<" "<<ans[3]<<" "<<ans[4]<<endl;

	}
	return 0;
}
/*
4
abcd
abca
abce
abcf
10
0000
1111
2222
3333
4444
5555
6666
7777
8888
9999

*/