• bzoj4241 历史研究


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4241

    【题解】

    和作诗相似。

    f[i,j]表示块i到块j的答案。

    g[i,j]表示1...i块中j出现次数。

    那么分块直接做即可。

    复杂度O(n根号n)

    跑的好慢啊。。

    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 1e5 + 10, N = 360, BLOCK = 320;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, q, B;
    int a[M], bl[M];
    int bst[N], bnd[N];
    vector<int> ps;
    int t[M];
    ll f[N][N];
    int g[N][M];
    
    inline void prepare(int x) {
        memset(t, 0, sizeof t);
        int tem = x;
        ll ans = 0;
        for (int i=bst[x]; i<=n; ++i) {
            ++t[a[i]];
            ans = max(ans, (ll)t[a[i]]*ps[a[i]-1]);
            if(i == bnd[tem]) {
                f[x][tem] = ans;
                ++tem;
            }
        }
    }
    
    int main() {
        scanf("%d%d", &n, &q);
        for (int i=1; i<=n; ++i) scanf("%d", a+i), ps.push_back(a[i]);
        sort(ps.begin(), ps.end());
        ps.erase(unique(ps.begin(), ps.end()), ps.end());
        for (int i=1; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + 1;
        for (int i=1; i<=n; ++i) bl[i] = (i-1)/BLOCK+1;
        B = bl[n];
        for (int i=1; i<=B; ++i) bst[i] = (i-1)*BLOCK+1, bnd[i] = min(n, i*BLOCK);
        for (int i=1; i<=B; ++i) prepare(i);
        for (int i=1; i<=B; ++i) {
            for (int j=1; j<=n; ++j) g[i][j] = g[i-1][j];
            for (int j=bst[i]; j<=bnd[i]; ++j) ++g[i][a[j]];
        }
        int l, r;
        while(q--) {
            scanf("%d%d", &l, &r);
            if(bl[l] == bl[r]) {
                ll ans = 0;
                for (int i=l; i<=r; ++i) t[a[i]] = 0;
                for (int i=l; i<=r; ++i) {
                    ++t[a[i]];
                    ans = max(ans, (ll)t[a[i]]*ps[a[i]-1]);
                }
                printf("%lld
    ", ans);
                continue;
            }
            ll ans = 0;
            if(bl[r]-bl[l] != 1) ans = f[bl[l]+1][bl[r]-1];
            for (int i=l; i<=bnd[bl[l]]; ++i) t[a[i]] = g[bl[r]-1][a[i]] - g[bl[l]][a[i]];
            for (int i=bst[bl[r]]; i<=r; ++i) t[a[i]] = g[bl[r]-1][a[i]] - g[bl[l]][a[i]];
            
            for (int i=l; i<=bnd[bl[l]]; ++i) {
                ++t[a[i]];
                ans = max(ans, (ll)t[a[i]]*ps[a[i]-1]);
            }
            for (int i=bst[bl[r]]; i<=r; ++i) {
                ++t[a[i]];
                ans = max(ans, (ll)t[a[i]]*ps[a[i]-1]);
            }
            printf("%lld
    ", ans);
        }
             
        return 0;
    }
    View Code
  • 相关阅读:
    从原生web组件到框架组件源码(二)
    从原生web组件到框架组件源码(一)
    拖拽滚动视图(一)
    SVG研究之路(一)下
    运算符
    编码
    格式化输出
    循环语句
    条件语句
    Python基础
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4241.html
Copyright © 2020-2023  润新知