zoukankan      html  css  js  c++  java
  • BZOJ 2724: [Violet 6]蒲公英( 分块 )

    虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 

    无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和,事实上我是写后缀和..因为下标从0开始..), cnt[i][j][k]表示第i块中的前j个数中,k出现次数。预处理O(N1.5), 询问每次O(N0.5), 总O((N+M)N0.5)

    -------------------------------------------------------------------

     #include<cstdio>

    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cctype>
     
    using namespace std;
     
    typedef pair<int, int> pii;
     
    const int maxb = 209;
    const int maxn = 40009;
     
    struct HASH {
    int h[maxn], n;
    HASH() : n(0) {
    }
    void Add(int v) {
    h[n++] = v;
    }
    void Work() {
    sort(h, h + n);
    n = unique(h, h + n) - h;
    }
    inline int Hash(int v) {
    return lower_bound(h, h + n, v) - h;
    }
    inline int _Hash(int v) {
    return h[v];
    }
    } H;
     
    int read() {
    char c = getchar();
    int ret = 0;
    for(; !isdigit(c); c = getchar()) c = getchar();
    for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
    return ret;
    }
     
    int seq[maxn];
    int sum[maxb][maxn], cnt[maxb][maxb][maxb], c[maxn], Id[maxb][maxn];
    int N, Q, B, n;
    pii Mode[maxb][maxb]; // <numId, cnt>
     
    void Init() {
    N = read(); Q = read();
    B = (int) sqrt(N);
    n = N / B;
    if(N % B) n++;
    for(int i = 0; i < N; i++)
    H.Add(seq[i] = read());
    H.Work();
    for(int i = 0; i < N; i++)
    seq[i] = H.Hash(seq[i]);
    memset(sum, 0, sizeof sum);
    for(int i = 0; i < N; i++)
    sum[i / B][seq[i]]++;
    for(int i = n; i--; )
    for(int j = 0; j < H.n; j++)
    sum[i][j] += sum[i + 1][j];
    for(int i = 0; i < n; i++) {
    memset(c, 0, sizeof c);
    int Max = 0, numId;
    for(int j = i; j < n; j++) {
    int p = j * B;
    for(int k = 0; k < B; k++, p++) if(++c[seq[p]] > Max) {
    numId = seq[p];
    Max = c[seq[p]];
    } else if(c[seq[p]] == Max) {
    numId = min(numId, seq[p]);
    }
    Mode[i][j] = make_pair(numId, Max);
    }
    }
    memset(cnt, 0, sizeof cnt);
    memset(Id, -1, sizeof Id);
    for(int i = 0; i < n; i++) {
    Id[i][H.n] = 0;
    int p = i * B;
    for(int j = 0; j < B; j++, p++) {
    int v = seq[p];
    if(!~Id[i][v])
    Id[i][v] = Id[i][H.n]++;
    cnt[i][j][Id[i][v]]++;
    }
    for(int j = B; j--; )
    for(int k = 0; k < Id[i][H.n]; k++)
    cnt[i][j][k] += cnt[i][j + 1][k];
    }
    }
     
    inline int getSum(int l, int r, int v) {
    return sum[l][v] - sum[r + 1][v];
    }
     
    inline int getCnt(int Block, int l, int r, int numId) {
    return cnt[Block][l][Id[Block][numId]] - cnt[Block][r + 1][Id[Block][numId]];
    }
     
    int solve(int l, int r) {
    if(l > r) swap(l, r);
    int lb = l / B, rb = r / B, ans, CNT = 0;
    memset(c, 0, sizeof c);
    if(rb - lb > 1) {
    pii &t = Mode[lb + 1][rb - 1];
    ans = t.first;
    CNT = t.second;
    for(int i = l; i / B == lb; i++) {
    int v = seq[i], Cnt = getCnt(lb, l % B, B - 1, v) + getCnt(rb, 0, r % B, v);
    Cnt += getSum(lb + 1, rb - 1, v);
    if(Cnt > CNT)
    ans = v, CNT = Cnt;
    else if(Cnt == CNT)
    ans = min(ans, v);
    }
    for(int i = rb * B; i <= r; i++) {
    int v = seq[i], Cnt = getCnt(lb, l % B, B - 1, v) + getCnt(rb, 0, r % B, v);
    Cnt += getSum(lb + 1, rb - 1, v);
    if(Cnt > CNT)
    ans = v, CNT = Cnt;
    else if(Cnt == CNT)
    ans = min(ans, v);
    }
    } else if(lb + 1 == rb) {
    for(int i = l; i / B == lb; i++) {
    int v = seq[i], Cnt = getCnt(lb, l % B, B - 1, v) + getCnt(rb, 0, r % B, v);
    if(Cnt > CNT)
    ans = v, CNT = Cnt;
    else if(Cnt == CNT)
    ans = min(ans, v);
    }
    for(int i = rb * B; i <= r; i++) {
    int v = seq[i], Cnt = getCnt(lb, l % B, B - 1, v) + getCnt(rb, 0, r % B, v);
    if(Cnt > CNT)
    ans = v, CNT = Cnt;
    else if(Cnt == CNT)
    ans = min(ans, v);
    }
    } else if(lb == rb) {
    for(; l <= r; l++) {
    int v = seq[l], Cnt = getCnt(lb, l % B, r % B, v);
    if(Cnt > CNT)
    ans = v, CNT = Cnt;
    else if(Cnt == CNT)
    ans = min(ans, v);
    }
    }
    return H._Hash(ans);
    }
     
    void Work() {
    int ans = 0;
    while(Q--) {
    int l = read(), r = read();
    printf("%d ", ans = solve((l + ans - 1) % N, (r + ans - 1) % N));
    }
    }
     
    int main() {
    Init();
    Work();
    return 0;
    }

    -------------------------------------------------------------------

    2724: [Violet 6]蒲公英

    Time Limit: 40 Sec  Memory Limit: 512 MB
    Submit: 1140  Solved: 373
    [Submit][Status][Discuss]

    Description

    Input

    修正一下

    l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1

    Output

    Sample Input

    6 3
    1 2 3 2 1 2
    1 5
    3 6
    1 5

    Sample Output

    1
    2
    1

    HINT


    修正下:


    n <= 40000, m <= 50000

    Source

  • 相关阅读:
    Json转换利器Gson之实例一-简单对象转化和带泛型的List转化 (转)
    JSON数据解析(转)
    JSON数据解析(GSON方式) (转)
    ASP.NET MVC学习之Ajax(完结)
    Newtonsoft.Json(Json.Net)学习笔记
    IDEA教程之导入maven项目
    idea language level 介绍
    .net core Asp.net Mvc Ef 网站搭建 vs2017 1)
    【MVC】快速构建一个图片浏览网站
    asp.netmvc 三层搭建一个完整的项目
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4989126.html
Copyright © 2011-2022 走看看