zoukankan      html  css  js  c++  java
  • The Preliminary Contest for ICPC Asia Shanghai 2019

    D. Counting Sequences I

    暴力搜索。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int MOD = 1000000007;
    
    map<vector<short>, short> m;
    vector<short> vec;
    
    void calc(int num1) {
        vector<short> tmp;
        if(num1)
            tmp.push_back(num1);
        int n = vec.size();
        int cur = 1;
        for(int i = 1; i < n; ++i) {
            if(vec[i] != vec[i - 1]) {
                tmp.push_back(cur);
                cur = 1;
            } else
                ++cur;
        }
        tmp.push_back(cur);
        sort(tmp.begin(), tmp.end());
        m[tmp]++;
    }
    
    void dfs(int last, int cur, ll pro, int sum) {
        for(int i = last; i <= 3000; ++i) {
            int tcur = cur + 1;
            ll tpro = pro * i;
            int tsum = sum + i;
            if(tpro - tsum + tcur > 3000)
                break;
    
            vec.push_back(i);
            calc(tpro - tsum);
            if(tpro * i - (tsum + i) + (tcur + 1) <= 3000)
                dfs(i, tcur, tpro, tsum);
            vec.pop_back();
        }
    }
    
    ll qpow(ll x, int n) {
        ll res = 1;
        while(n) {
            if(n & 1)
                res = res * x % MOD;
            x = x * x % MOD;
            n >>= 1;
        }
        return res;
    }
    
    int ans[3005], prod[3005], invprod[3005];
    
    void Init() {
        dfs(2, 0, 1, 0);
        prod[0] = 1;
        for(int i = 1; i <= 3000; ++i) {
            prod[i] = 1ll * prod[i - 1] * i % MOD;
            invprod[i] = qpow(prod[i], MOD - 2);
        }
        for(auto mi : m) {
            ll sum = 1;
            int len = 0;
            for(auto vi : mi.first) {
                len += vi;
                sum = (sum * invprod[vi]) % MOD;
            }
            sum = (sum * prod[len]) % MOD;
            sum = (sum * mi.second) % MOD;
            ans[len] = (sum + ans[len]) % MOD;
        }
        ans[0] = ans[1] = 0;
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        Init();
        int T;
        scanf("%d", &T);
        while(T--) {
            int n;
            scanf("%d", &n);
            printf("%d
    ", ans[n]);
        }
    }
    

    H. Luhhy's Matrix

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned int uint;
    
    struct Matrix {
        bitset<16> ma[16];
        Matrix() {}
        void Clear() {
            for(int i = 0; i < 16; ++i)
                ma[i] = 0;
        }
        void one() {
            Clear();
            for(int i = 0; i < 16; ++i)
                ma[i][i] = 1;
        }
        Matrix operator*(const Matrix& t)const {
            Matrix res;
            for(int i = 0; i < 16; ++i) {
                for(int k = 0; k < 16; ++k) {
                    if(ma[i][k])
                        res.ma[i] ^= t.ma[k];
                }
            }
            return res;
        }
    };
    
    stack<Matrix> Stack1, Stack2;
    Matrix ProdStack1, tmp;
    
    void Push(uint seed, uint lastans) {
        seed ^= lastans;
        for(int i = 0; i < 16; ++i) {
            seed ^= seed * seed + 15;
            for(int j = 0; j < 16; ++j)
                tmp.ma[i][j] = (seed >> j) & 1;
        }
        Stack1.push(tmp);
        ProdStack1 = tmp * ProdStack1;
    }
    
    void Pop() {
        if(Stack2.empty()) {
            tmp.one();
            while(!Stack1.empty()) {
                tmp = tmp * Stack1.top();
                Stack1.pop();
                Stack2.push(tmp);
            }
            ProdStack1.one();
        }
        Stack2.pop();
    }
    
    uint ans[16][16];
    
    inline void InitAns() {
        uint p17[16], p19[16];
        p17[0] = 1, p19[0] = 1;
        for(int i = 1; i < 16; ++i) {
            p17[i] = p17[i - 1] * 17u;
            p19[i] = p19[i - 1] * 19u;
        }
        for(int i = 0; i < 16; ++i) {
            for(int j = 0; j < 16; ++j)
                ans[i][j] = p17[i] * p19[j];
        }
    }
    
    uint Calc() {
        if(Stack1.empty() && Stack2.empty())
            return 0;
        tmp = ProdStack1;
        if(!Stack2.empty())
            tmp = tmp * Stack2.top();
        uint res = 0;
        for(int i = 0; i < 16; ++i) {
            for(int j = 0; j < 16; ++j) {
                if(tmp.ma[i][j])
                    res += ans[i][j];
            }
        }
        return res;
    }
    
    inline void Read(uint &x) {
        x = 0;
        char ch = getchar();
        while(ch < '0' || ch > '9')
            ch = getchar();
        while(ch >= '0' && ch <= '9')
            x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    }
    
    inline void Write(uint x) {
        if(x < 10)
            putchar(x + '0');
        else {
            Write(x / 10);
            putchar(x % 10 + '0');
        }
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        InitAns();
        uint T;
        Read(T);
        while(T--) {
            while(!Stack1.empty())
                Stack1.pop();
            while(!Stack2.empty())
                Stack2.pop();
            ProdStack1.one();
            uint n, t, seed, lastans = 0;
            Read(n);
            for(int i = 1; i <= n; ++i) {
                Read(t), Read(seed);
                if(t == 1)
                    Push(seed, lastans);
                else
                    Pop();
                lastans = Calc();
                Write(lastans);
                putchar('
    ');
            }
        }
    }
    

    unsigned short优化明显,静态stack倒是没啥用。仔细观察之后两个栈可以共用同一段内存。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned int uint;
    
    struct Matrix {
        unsigned short ma[16];
        Matrix() {}
        void Clear() {
            memset(ma, 0, sizeof(ma));
        }
        void one() {
            for(int i = 0; i < 16; ++i)
                ma[i] = 1 << i;
        }
        Matrix operator*(const Matrix& t)const {
            Matrix res;
            res.Clear();
            for(int i = 0; i < 16; ++i) {
                for(int k = 0; k < 16; ++k) {
                    if((ma[i] >> k) & 1)
                        res.ma[i] ^= t.ma[k];
                }
            }
            return res;
        }
    };
    
    const int MAXN = 50000;
    int s1, s2;
    Matrix Stack[50000 + 5];
    Matrix ProdStack1, tmp;
    
    void Push(uint seed, uint lastans) {
        seed ^= lastans;
        for(int i = 0; i < 16; ++i) {
            seed ^= seed * seed + 15;
            tmp.ma[i] = seed;
        }
        Stack[++s1] = tmp;
        ProdStack1 = tmp * ProdStack1;
    }
    
    void Pop() {
        if(s2 > MAXN) {
            tmp.one();
            while(s1 > 1) {
                tmp = tmp * Stack[s1--];
                Stack[--s2] = tmp;
            }
            --s1;
            ProdStack1.one();
        } else
            ++s2;
    }
    
    uint ans[16][16];
    
    inline void InitAns() {
        uint p17[16], p19[16];
        p17[0] = 1, p19[0] = 1;
        for(int i = 1; i < 16; ++i) {
            p17[i] = p17[i - 1] * 17u;
            p19[i] = p19[i - 1] * 19u;
        }
        for(int i = 0; i < 16; ++i) {
            for(int j = 0; j < 16; ++j)
                ans[i][j] = p17[i] * p19[j];
        }
    }
    
    uint Calc() {
        if(s1 == 0 && s2 > MAXN)
            return 0;
        tmp = ProdStack1;
        if(s2 <= MAXN)
            tmp = tmp * Stack[s2];
        uint res = 0;
        for(int i = 0; i < 16; ++i) {
            for(int j = 0; j < 16; ++j) {
                if((tmp.ma[i] >> j) & 1)
                    res += ans[i][j];
            }
        }
        return res;
    }
    
    inline void Read(uint &x) {
        x = 0;
        char ch = getchar();
        while(ch < '0' || ch > '9')
            ch = getchar();
        while(ch >= '0' && ch <= '9')
            x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    }
    
    inline void Write(uint x) {
        if(x < 10)
            putchar(x + '0');
        else {
            Write(x / 10);
            putchar(x % 10 + '0');
        }
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        InitAns();
        uint T;
        Read(T);
        while(T--) {
            s1 = 0, s2 = MAXN + 1;
            ProdStack1.one();
            uint n, t, seed, lastans = 0;
            Read(n);
            for(int i = 1; i <= n; ++i) {
                Read(t), Read(seed);
                if(t == 1)
                    Push(seed, lastans);
                else
                    Pop();
                lastans = Calc();
                Write(lastans);
                putchar('
    ');
            }
        }
    }
    
  • 相关阅读:
    OpenRisc-52-run openrisc&orpmon on ml501 board
    PHP之APC缓存详细介绍(转)
    ios 使用GCD 多线程 教程
    poj2454
    尝鲜delphi开发android/ios_环境搭建
    HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
    jQuery 表格排序插件 Tablesorter 使用
    Oracle 常见错误
    安卓开发44:解决 INSTALL_FAILED_UID_CHANGED 等问题
    Java的native方法
  • 原文地址:https://www.cnblogs.com/Inko/p/11525037.html
Copyright © 2011-2022 走看看