zoukankan      html  css  js  c++  java
  • Codeforces Round #708 (Div. 2)

    C1-k-LCM (easy version)

    分情况讨论一下

    void solve(){
        if(n & 1){
            cout << 1 << " " << (n / 2) << " " << (n / 2) << '
    ';
        }
        else if(n % 4 == 0){
            cout << (n / 2) << " " << (n / 4) << " " << (n / 4) << '
    ';
        }
        else{
            cout << 2 << " " << ((n - 2) / 2) << " " << ((n - 2) / 2) << '
    ';
        }
    }
    

    C2-k-LCM (hard version)

    转化成C1

    void solve() {
        for(int i = 1;i <= k - 3;i++){
            cout << 1 << " ";n--;
        }
        if (n & 1) {
            cout << 1 << " " << (n / 2) << " " << (n / 2) << '
    ';
        }
        else if (n % 4 == 0) {
            cout << (n / 2) << " " << (n / 4) << " " << (n / 4) << '
    ';
        }
        else {
            cout << 2 << " " << ((n - 2) / 2) << " " << ((n - 2) / 2) << '
    ';
        }
    }
    

    D-Genius

    看完官方的题解感觉挺巧妙的, 设 (f[i]) 表示以 (i) 为终点的最大得分值, 则把边按照从小到大的顺序来枚举,进行转移即可

    for(int i = 2;i <= n;i++){
        for(int j = i - 1;j >= 1;j--){
        	
        }
    }
    

    这样的枚举顺序可以保证边权 ((abs(c_i - c_j))) 严格递增

    void solve() {
        vector<ll>f;
        f.resize(n + 1, 0);
        for (int i = 2;i <= n;i++) {
            for (int j = i - 1;j >= 1;j--) {
                ll fi = f[i], fj = f[j], p = abs(s[i] - s[j]);
                if (tag[i] != tag[j]) {
                    f[i] = max(f[i], fj + p);
                    f[j] = max(f[j], fi + p);
                }
            }
        }
        cout << *max_element(f.begin(), f.end()) << '
    ';
    }
    

    E1-Square-free division (easy version)

    直接质因数分解然后次数全部模 2 ,转化为分成尽可能少的区间, 使得所有区间内的数两两各不相同,扫一遍就可以

    E-2Square-free division (hard version)

    (f[i][j]) 表示前 (i) 个数,使用了 (j) 次转变的最小段数, 设 (L[i][j]) 表示前 (i) 个数中, (i) 所属的段使用了 (j) 次转变所能到达的最左边的下标, 即 ([L[i][j], i]) 这个段使用了 (j) 次转变,且无法继续向左延申

    处理 (L) 的时候可以 (O(nk)) 处理出来, 枚举 (k) ,然后扫一遍。

    转移的时候

    for (int i = 1;i <= n;i++) {
            for (int j = 0;j <= k;j++) {
                if (j > 0)f[i][j] = f[i][j - 1];
                for (int lst = 0;lst <= j;lst++) {
                    f[i][j] = min(f[i][j], f[L[i][lst] - 1][j - lst] + 1);
                }
            }
        }
    
    #include<bits/stdc++.h>
    using namespace std;
    #define what(x) cerr << #x << " is " << x << endl;
    #define getall(x,ed) cerr << #x << ": 	";debug(x,ed);
    #define IO ios::sync_with_stdio(0);cin.tie(0);
    std::mt19937 rnd(time(0));
    template<typename T>
    void debug(T begin, T ed) {
        for (T i = begin;i != ed;i++)cout << *i << '	';cout << '
    ';
    }
    
    const int N = 1e7 + 10;
    typedef long long ll;
    
    vector<int>prime, vis, fp, A;
    void init() {
        vis.resize(N, 0);fp.resize(N, 0);
    
        for (int i = 2;i < N;i++) {
            if (!vis[i]) {
                prime.emplace_back(i);
                fp[i] = i;
            }
            for (auto& p : prime) {
                if (i * p >= N)break;
                vis[p * i] = 1;
                fp[p * i] = p;
                if (i % p == 0)break;
            }
        }
    }
    
    int T, n, k;
    
    void read_and_init() {
        cin >> n >> k;
        A.resize(n + 1, 0);
        for (int i = 1;i <= n;i++) {
            int x;cin >> x;
            A[i] = 1;
            while (x != 1) {
                int p = fp[x];
                x /= p;
                if (fp[x] == p) {
                    x /= p;
                }
                else {
                    A[i] *= p;
                }
            }
            //cout << A[i] << '
    ';
        }
    }
    unordered_map<int, int>cnt;
    void solve() {
        vector<vector<int>>f(n + 1, vector<int>(k + 1, 1e9));
        vector<vector<int>>L(n + 1, vector<int>(k + 1, 0));
    
        for (int j = 0;j <= k;j++) {
            int now = 0;
            int idx = 1;
            cnt.clear();
            for (int i = 1;i <= n;i++) {
    
                if (cnt.count(A[i]))now++;
                cnt[A[i]]++;
                //cout << i << " " << now << " " << idx << '
    ';
                //for(auto&x : cnt)cout << x.first << " : " << x.second << '
    ';
                if (now <= j)L[i][j] = idx;
                else {
                    while (idx <= i and now > j) {
                        if (cnt[A[idx]] >= 2)now--;
                        if (!--cnt[A[idx]])cnt.erase(A[idx]);
                        idx++;
                    }
                    L[i][j] = idx;
                }
                //what(L[i][j]);
            }
        }
    
        for (auto& c : f[0])c = 0;
    
        for (int i = 1;i <= n;i++) {
            for (int j = 0;j <= k;j++) {
                if (j > 0)f[i][j] = f[i][j - 1];
                for (int lst = 0;lst <= j;lst++) {
                    f[i][j] = min(f[i][j], f[L[i][lst] - 1][j - lst] + 1);
                }
            }
        }
        cout << f[n][k] << '
    ';
    
    
    }
    int main() {
        IO;
        init();
        cin >> T;
        while (T--) {
            read_and_init();
            solve();
        }
    }
    
  • 相关阅读:
    组装query,query汇总,query字段
    POJ 1276, Cash Machine
    POJ 1129, Channel Allocation
    POJ 2531, Network Saboteur
    POJ 1837, Balance
    POJ 3278, Catch That Cow
    POJ 2676, Sudoku
    POJ 3126, Prime Path
    POJ 3414, Pots
    POJ 1426, Find The Multiple
  • 原文地址:https://www.cnblogs.com/sduwh/p/14555636.html
Copyright © 2011-2022 走看看