【题解】P6521 [CEOI 2010] pin (day2)

P6521 [CEOI 2010] pin (day2)

题意

给定 \(n\) 个长度为 \(4\) 的字符串,求出有多少对字符串满足恰好 \(D\) 个对应位置的字符不同。

题解

知识点:二项式反演,组合数学。

启发:

  • 枚举匹配状态计算 \(f\) 函数。

\(d\leftarrow 4-d\),那么求的就变成了恰好 \(d\) 个对应位置的字符相同的对数。

\(g_m\) 为恰好有 \(m\) 个位置相同的对数。

\(f_m\) 为钦定 \(m\) 个位置相同,其余随意的对数。

所以会满足,

\[\large \displaystyle f_m=\sum_{i=m}^4 \binom{i}{m} \times g_i \]

二项式反演得到,

\[\large \displaystyle g_m=\sum_{i=m}^4 \binom{i}{m} \times (-1)^{i-m} f_i \]

这题的 \(f_m\) 没有固定的式子,不过字符串长度很小,可以枚举 \(s\in [0,15]\) 表示四个位的状态,每次扫一遍,只关心为 \(1\) 的位置上的字符,做一遍哈希,对哈希值相同的两两组合计入 \(res\),最后累加到 \(f_{\operatorname{popcount(s)}}\) 即可。

答案即为 \(g_d\)

#include<bits/stdc++.h>
using namespace std;

#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define per(i,l,r) for(int i=(r);i>=(l);--i)
#define pr pair<int,int>
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define sz(x) (x).size()
#define bg(x) (x).begin()
#define ed(x) (x).end()

#define N 202504
#define int long long

int n,d,f[N],C[10][10];
string a[N];

inline int pcnt(int x){
    int ans=0;

    while(x){
        ans+=x&1;
        x>>=1;
    }

    return ans;
}

inline void init(int lim){
    rep(i,0,lim){
        C[i][0]=1;
    }

    rep(i,1,lim){
        rep(j,1,i){
            C[i][j]=C[i-1][j]+C[i-1][j-1];
        }
    }
}

inline int neg(int x){
    return x&1?-1:1;
}

signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    cin>>n>>d;

    d=4-d;
    rep(i,1,n){
        cin>>a[i];
    }

    rep(s,0,15){
        unordered_map<int,int>mp;

        rep(i,1,n){
            int ha=0;

            rep(j,0,3){
                if(!((s>>j)&1)){
                    continue;
                }

                ha=ha*131+a[i][j];
            }

            mp[ha]++;
        }

        int p=pcnt(s);

        for(auto x:mp){
            f[p]+=x.se*(x.se-1)/2;
        }
    }

    init(4);

    int ans=0;

    rep(i,d,4){
        ans+=C[i][d]*neg(i-d)*f[i];
    }

    cout<<ans;

    return 0;
}
posted @ 2025-06-28 15:00  Lucyna_Kushinada  阅读(34)  评论(2)    收藏  举报