关闭

【bzoj4241】历史研究

485人阅读 评论(0) 收藏 举报
分类:

  这题也是坑了好久>_<
  之前whx带我刷JOI的时候本来应该要做的。。。可是太懒没有写。。。
  区间询问加权众数。
分块,预处理出块和块之间的答案,记录到第i个块数字x出现了多少次。然后查询的时候和普通众数基本一样,就是乘了个权值而已。
要离散化。
时间复杂度O(nlogn+mn)
昨晚写的常数太烂了。。。用了struct,数组开大了,狂M
然后卡了卡空间,狂RE doge
然后查了很久发现有个边界写的有点问题
改完之后就无限TLE辣QAQ
电脑课花了20min来rewrite结果就A掉了smg。。。。

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a,_=b;i<=_;i++)
#define per(i,a,b) for(int i=a,_=b;i>=_;i--)
#define maxn 100007
#define maxb 331

inline int rd() {
    char c = getchar();
    while (!isdigit(c)) c = getchar() ; int x = c - '0';
    while (isdigit(c = getchar())) x = x * 10 + c - '0';
    return x;
}

typedef long long ll;

inline void upmax(ll&a , ll b) { if (a < b) a = b ; }

typedef int arr_int[maxn];
typedef ll  arr_ll [maxn];
typedef int blk_int[maxb];
typedef ll  blk_ll [maxb];

int n , m , all , len , tot;
arr_int h , a , cnt , belong;
blk_ll  ans[maxb];
arr_int sum[maxb] , st , ed;

void input() {
    n = rd() , m = rd();
    rep (i , 1 , n) h[i] = a[i] = rd();
    sort(h + 1 , h + n + 1);
    all = unique(h + 1 , h + n + 1) - h - 1;
    rep (i , 1 , n) a[i] = lower_bound(h + 1 , h + all + 1 , a[i]) - h;
}

void init_block() {
    len = (int) sqrt(n + 0.5);
    rep (i , 1 , n)
        belong[i] = (i - 1) / len + 1;
    tot = belong[n];
    rep (i , 1 , tot)
        st[i] = (i - 1) * len + 1 , ed[i] = i * len;
    ed[tot] = n;
    rep (i , 1 , n)
        sum[belong[i]][a[i]] ++;
    rep (i , 1 , tot)
        rep(x , 1 , all)
            sum[i][x] += sum[i - 1][x];
    rep (i , 1 , tot) {
        rep (j , st[i] , n) cnt[a[j]] = 0;
        ll mx = 0;
        rep (j , st[i] , n) {
            int x = a[j];
            cnt[x] ++;
            upmax(mx , (ll) cnt[x] * h[x]);
            ans[i][belong[j]] = mx;
        }
    }
}

void query(int l , int r) {
    ll mx = 0;
    int L = belong[l] , R = belong[r];
    if (L == R) {
        rep (i , l , r) cnt[a[i]] ++ ;
        rep (i , l , r) {
            int x = a[i];
            if (!cnt[x]) continue;
            upmax(mx , (ll) cnt[x] * h[x]);
            cnt[x] = 0;
        }
    } else {
        if (L + 1 < R)
            mx = ans[L + 1][R - 1];
        rep (i , l , ed[L]) cnt[a[i]] ++ ;
        rep (i , st[R] , r) cnt[a[i]] ++ ;
        rep (i , l , ed[L]) {
            int x = a[i];
            if (!cnt[x]) continue;
            ll ts = sum[R - 1][x] - sum[L][x] + cnt[x];
            ts *= h[x] , cnt[x] = 0;
            upmax(mx , ts);
        }
        rep (i , st[R] , r) {
            int x = a[i];
            if (!cnt[x]) continue;
            ll ts = sum[R - 1][x] - sum[L][x] + cnt[x];
            ts *= h[x] , cnt[x] = 0;
            upmax(mx , ts);
        }
    }
    printf("%lld\n" , mx);
}

void solve() {
    init_block();
    memset(cnt , 0 , sizeof cnt);
    rep (i , 1 , m) {
        int l = rd() , r = rd();
        query(l , r);
    }
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.txt" , "r" , stdin);
        freopen("data.out" , "w" , stdout);
    #endif
    input();
    solve();
    return 0;
}
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:89696次
    • 积分:2252
    • 等级:
    • 排名:第17458名
    • 原创:135篇
    • 转载:0篇
    • 译文:0篇
    • 评论:44条
    小伙伴
    大神犇
    最新评论