• ICPC2017青岛


    Floppy Cube

    题解

    Pólya定理用于计算在置换下的所有本质不同的方案数。

    可以发现,操作产生的所有置换都可以通过横向旋转90度,纵向旋转180度,左侧一列转动180度这三个置换产生。只需bfs,通过这三个置换搜索出所有可能的置换,假设这个置换的集合是(G),颜色数为(c),答案即为

    [frac{1}{|G|}sumlimits_{gin G}{c^{f(g)}} ]

    其中(f(g))代表置换(g)能拆分成的不相交的循环置换的数量。

    用于模数和颜色数都比较大,值域(10^9)。模数(P)不确定的情况下,要取模后除去一个数(k),无法确保有逆元。假如最终结果(假设为(n))可以被(k)整除,那么有

    [(nmod Pk)= (kfrac{n}{k} mod Pk) \ k(frac{n}{k} mod P) = (n mod Pk) \ (frac{n}{k} mod P)=frac{(n mod Pk)}{k} ]

    因此为了除去(|G|),只需对结果模(P|G|),最后除去(|G|)即可。

    #include <bits/stdc++.h>
    
    #define endl '
    '
    #define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
    #define mp make_pair
    #define seteps(N) fixed << setprecision(N) 
    typedef long long ll;
    
    using namespace std;
    /*-----------------------------------------------------------------*/
    
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    #define INF 0x3f3f3f3f
    
    const int N = 3e5 + 10;
    const double eps = 1e-5;
    
    vector<int> g1 = {6, 3, 0, 7, 4, 1, 8, 5, 2, 15, 12, 9, 16, 13, 10, 17, 14, 11, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 20};
    vector<int> g2 = {15, 16, 17, 12, 13, 14, 9, 10, 11, 6, 7, 8, 3, 4, 5, 0, 1, 2, 26, 25, 24, 23, 22, 21, 20, 19, 18, 29, 28, 27};
    vector<int> g3 = {0, 1, 17, 3, 4, 14, 6, 7, 11, 9, 10, 8, 12, 13, 5, 15, 16, 2, 18, 19, 24, 23, 22, 21, 20, 25, 26, 27, 28, 29};
    
    bool chk(vector<int> &g) {
        vector<int> vis(30, 0);
        for(int i = 0; i < g.size(); i++) vis[g[i]] = 1;
        for(int i = 0; i < 30; i++) if(!vis[i]) return false;
        return true;
    }
    
    set<vector<int> > ans;
    int cnt[100];
    
    int cal(const vector<int>& pi) {
        vector<int> vis(30, 0);
        int res = 0;
        for(int i = 0; i < pi.size(); i++) {
            if(vis[i]) continue;
            res++;
            int cur = pi[i];
            while(!vis[cur]) {
                vis[cur] = 1;
                cur = pi[cur];
            }
        }
        return res;
    }
    
    vector<int> change(const vector<int>& d, const vector<int> &g) {
        vector<int> nt(30);
        for(int i = 0; i < 30; i++) {
            nt[i] = d[g[i]];
        }
        return nt;
    }
    
    void solve(vector<int> s) {
        queue<vector<int>> q;
        q.push(s);
        ans.insert(s);
        while(!q.empty()) {
            auto cur = q.front();
            q.pop();
            vector<int> nt;
            nt = change(cur, g1);
            if(!ans.count(nt)) {ans.insert(nt); q.push(nt);}
            nt = change(cur, g2);
            if(!ans.count(nt)) {ans.insert(nt); q.push(nt);}
            nt = change(cur, g3);
            if(!ans.count(nt)) {ans.insert(nt); q.push(nt);}
        }
        for(auto p : ans) {
            cnt[cal(p)]++;
        }
    }
    
    ll mpw(ll x, int p) {
        ll res = 1;
        while(p--) {
            res *= x;
        }
        return res;
    }
    
    ll qmul(ll x, ll y, ll m) {
        return (__int128)x * y % m;
    }
    
    inline ll qpow(ll a, ll b, ll m) {
        ll res = 1;
        while(b) {
            if(b & 1) res = qmul(res, a, m);
            a = qmul(a, a, m);
            b = b >> 1;
        }
        return res;
    }
    
    int main() {
        IOS;
        vector<int> s;
        for(int i = 0; i < 30; i++) s.push_back(i);
        solve(s);
        ll tot = ans.size();
        int t;
        cin >> t;
        while(t--) {
            ll n, p;
            cin >> n >> p;
            p *= tot;
            ll ans = 0;
            for(int i = 1; i <= 30; i++) {
                ans = (ans + cnt[i] * qpow(n, i, p) % p) % p;
            }
            assert(ans % tot == 0);
            cout << ans / tot << endl;
        }
    }
    
  • 相关阅读:
    Python语言解析xml文件
    运行manage.py db shell出错
    ImportError: No module named win32com.client
    ImportError: No module named urllib2
    《演讲之禅》 读书笔记
    no such table: django_admin_log
    2 策略模式(2)
    1 简单工厂模式
    2 策略模式(1)
    无言
  • 原文地址:https://www.cnblogs.com/limil/p/15490937.html
Copyright © 2020-2023  润新知