zoukankan      html  css  js  c++  java
  • Atcoder Beginner Contest 200 F

    传送门

    网上看到一个挺妙的解法


    题意

    规定一个 (01) 串的价值为其最少需要的区间 (01) 翻转次数,使得其成为同色的串。

    初始给定一个含有 (01) 与若干 (?) 字符的初始串 (S) ,把 (K)(S) 收尾相接得到串 (T) 。求将 (T) 中每个 (?) 都换为 (0)(1) 时,所有串的价值总和。答案对 (10^9+7) 取模。


    分析

    先不考虑 (?) 的限制。

    考虑将串收尾相接,变成一个环。不难想到,环上的 (01) “脉冲”个数一定是偶数。且稍加观察可以得到,当“脉冲”数量为 (n) 时,最少需要的区间翻转次数就是 ({nover 2})

    由于等效于一个“脉冲”的贡献是 ({1over 2}),由于其总数为偶数,所以正确性没有影响。

    (K) 个串收尾相连时,只需要算出第一个串的“脉冲”贡献,然后直接乘 (K) 即可。


    考虑 (?) 的限制。

    当出现 (?) 时,不妨记为 (s_i=?) 。((s_0=s_nwedge s_{n+1}=s_1)

    则从概率角度,(s_i)({1over 2}) 的概率是 (0),有 ({1over 2}) 的概率是 (1)

    (s_{i-1} eq ?) 时,统计量中,一半的 (s_{i-1}s_i) 贡献“有脉冲”,为 ({1over 2}) ;一半的 (s_{i-1}s_i) 贡献“无脉冲”,为 (0)

    等效于一个 (s_{i-1}s_i) 的贡献为 ({1over 4}) ,同样由于出现 (?) 时,总数为偶数,所以正确性没有影响。

    同理可得,(s_{i+1} eq ?) 时一个 (s_is_{i+1}) 的贡献也为 ({1over 4})

    而出现 (s_is_{i+1}=??) 时,从概率角度,(00, 01, 10, 11) 的出现概率都是 ({1over 4});因此有无脉冲的概率仍均是 ({1over 2}) ,贡献同样也为 ({1over 4})

    所以同样当 (K) 个串相连时,只需算出第一个串的“脉冲”贡献和 (?) 贡献,然后直接乘 (Kcdot 2^{Kq}) 算出答案。


    代码

    记得特判 (K=1, |S|=1) 的情况即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef double db;
    typedef pair<ll, ll> pii;
    const int MOD=1e9+7;
    inline ll fpow(ll a,ll x) { ll ans=1; for(;x;x>>=1,a=a*a%MOD) if(x&1) ans=ans*a%MOD; return ans; }
    inline ll sumq(const string &s) { ll ans=0; for(auto c : s) ans+=(c=='?'); return ans; }
    inline ll sumf(const string &s){
        ll ans=0;
        char lstc=s.back();
        for(int i=0;i<s.size();lstc=s[i], ++i)
            if(lstc=='?'||s[i]=='?') ++ans;
            else if(lstc!=s[i]) ans+=2;
        return ans*fpow(4, MOD-2)%MOD;
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        string s;
        ll k;
        cin>>s>>k;
        cout<<fpow(2, k*sumq(s))*k%MOD*sumf(s)%MOD*(s.size()>1||k>1);
        cout.flush();
        return 0;
    }
    

    感想

    第一次见识到这种用概率和期望反过来求统计的方式,非常的 amazing 啊!

    说起来,莫名其妙想到量子计算的纠缠态

  • 相关阅读:
    HDU 1010 Tempter of the Bone(DFS剪枝)
    HDU 1013 Digital Roots(九余数定理)
    HDU 2680 Choose the best route(反向建图最短路)
    HDU 1596 find the safest road(最短路)
    HDU 2072 单词数
    HDU 3790 最短路径问题 (dijkstra)
    HDU 1018 Big Number
    HDU 1042 N!
    NYOJ 117 求逆序数 (树状数组)
    20.QT文本文件读写
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/14826647.html
Copyright © 2011-2022 走看看