解题报告：HDU_6123 Destroy the cube (容斥+三元环计数)

#include<bits/stdc++.h>

#define LL long long
#define pii pair< int , int >
#define fi first
#define se second
const int N = 6e4+5;
using namespace std;

int num[2][3][2][N],n,nn,all[2];
map< unsigned , int > S[2];
vector<int>G[2][N],pos;
vector< pii >A;

bool has[N];

inline unsigned oper(unsigned a,unsigned b){return (a<<16) | b ;}
inline bool check(int a,int b,int k) {return  S[k].find(oper(a,b))!= S[k].end();}

inline void add(int a,int b,int k){
if( ++S[k][oper(a,b)]==1 )G[k][a].emplace_back(b),++all[k];
if(a!=b&&++S[k][oper(b,a)]==1)G[k][b].emplace_back(a),++all[k];
++num[k][0][0][a];++num[k][0][1][b];
++num[k][1][0][a];++num[k][1][1][b];
++num[k][2][0][b];++num[k][2][1][a];
}

int res = 0;
for(int i=0;i<A.size();i++){
pii& t = A[i];
if(has[t.se]||has[t.fi])res += (t.fi==t.se?12:24);
}return res;
}

inline int get(int a,int b,int c){
int mi = min(a,min(b,c));
int mx = max(a,max(b,c));
int mm = a+b+c-mi-mx;
int res = 3 - (mi==mm) - (mm==mx);
if(res==3)return 6;
return res==1?1:3;
}

{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

inline LL work(int k){
LL x = k?1:8 , ans = 0;
int l = k?n:nn , m = sqrt(all[k]+0.5) ;
for(int i=1;i<=l;i++){
ans += x*num[k][0][0][i]*num[k][1][0][i];
ans += x*num[k][0][1][i]*num[k][2][0][i];
ans += x*num[k][1][1][i]*num[k][2][1][i];
}pos.clear();
for(int i=1,a,b;i<=l;++i)
if(G[k][i].size()>m)pos.emplace_back(i);
else for(int j=0;j<G[k][i].size();j++)if(G[k][a=G[k][i][j]].size()>m||a>=i)
for(int q=j;q<G[k][i].size();q++)if((G[k][b=G[k][i][q]].size()>m||b>=i)&&check(a,b,k))
ans-=x*get(i,b,a);
for(int i=0;i<pos.size();i++)for(int j=i;j<pos.size();j++)if(check(pos[i],pos[j],k))
for(int q=j;q<pos.size();q++)if(check(pos[j],pos[q],k)&&check(pos[i],pos[q],k))
ans -= x*get(pos[i],pos[j],pos[q]);
return ans-x*3*all[k]*l;
}

int main()
{
while(T--){S[0].clear();S[1].clear();A.clear();
memset(num,0,sizeof(num));all[0] = all[1] = 0;
for(int i=1;i<=n;i++)G[0][i].clear(),G[1][i].clear(),has[i]=0;
while(m--){
has[a]=true;
int aa = n - a + 1  , bb = n - b + 1;
continue;
}if(n&1)A.emplace_back(pii(a,b));