P6521 [CEOI2010 day2] pin
Solution
\(\texttt{E}\color{red}{\texttt{ricQian}}\) 很有精神!\(\color{white}{114514}\)
我们都要像他一样有精神!\(\color{white}{114514}\)
\(\texttt{E}\color{red}{\texttt{ricQian}}\) 说你可以设一个 \(d\) 表示恰好某些位置相同的对数,\(p\) 表示至少某些位置相同的对数,\(D\) 表示恰好几个位置相同的对数,\(P\) 表示至少几个位置相同的对数。\(\color{white}{114514}\)
\(\texttt{E}\color{red}{\texttt{ricQian}}\) 说 \(P\) 和 \(p\) 都可以直接求。于是我们来考虑 \(D\) 和 \(d\) 的求法。\(\color{white}{114514}\)
\(\texttt{E}\color{red}{\texttt{ricQian}}\) 觉得你很逊,于是他来帮你颓式子:\(\color{white}{114514}\)
\[\begin{aligned}
D_4&=P_4\\
D_3&=d_{123}+d_{124}+d_{134}+d_{234}\\
&=(p_{123}-p_{1234})+(p_{124}-p_{1234})+(p_{134}-p_{1234})+(p_{234}-p_{1234})\\
&=P_3-4D_4\\
D_2&=d_{12}+d_{13}+d_{14}+d_{23}+d_{24}+d_{34}\\
&=(p_{12}-d_{123}-d_{124}-d_{1234})+(p_{13}-d_{123}-d_{134}-d_{1234})+(p_{14}-d_{124}-d_{134}-d_{1234})+(p_{23}-d_{123}-d_{234}-d_{1234})+(p_{24}-d_{124}-d_{234}-d_{1234})+(p_{34}-d_{134}-d_{234}-d_{1234})\\
&=P_2-3D_3-6D_4\\
D_1&=d_1+d_2+d_3+d_4\\
&=(p_1-d_{12}-d_{13}-d_{14}-d_{123}-d_{124}-d_{134}-d_{1234})+(p_2-d_{12}-d_{23}-d_{24}-d_{123}-d_{124}-d_{234}-d_{1234})+(p_3-d_{13}-d_{23}-d_{34}-d_{123}-d_{234}-d_{134}-d_{1234})+(p_4-d_{14}-d_{24}-d_{34}-d_{124}-d_{134}-d_{234}-d_{1234})\\
&=P_1-2D_2-3D_3-4D_4
\end{aligned}
\]
哇!这真是太有精神了吧!真的没有再比这样的事情更有精神了!\(\color{white}{114514}\)
我们的 \(\texttt{E}\color{red}{\texttt{ricQian}}\) 真是太厉害了!大家快来膜拜 \(\texttt{E}\color{red}{\texttt{ricQian}}\)!!!\(\color{white}{114514}\)
Code
#define int long long
using namespace std;
const int MAXN=5e4+10;
map<string,int> cnt;
string s[MAXN];
int P[MAXN],D[MAXN];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n,d;cin>>n>>d;
rep(i,1,n) cin>>s[i];
rep(i,1,15){
int ppc=__builtin_popcount(i);
cnt.clear();
rep(j,1,n){
string t;
rep(k,0,3)
if(i&(1<<k))
t+=s[j][k];
P[ppc]+=(cnt[t]++);
}
}D[4]=P[4];
D[3]=P[3]-4*D[4];
D[2]=P[2]-3*D[3]-6*D[4];
D[1]=P[1]-2*D[2]-3*D[3]-4*D[4];
if(d==4) cout<<n*(n-1)/2-D[1]-D[2]-D[3]-D[4]<<'\n';
else cout<<D[4-d]<<'\n';
return 0;
}