• [分块][离散化] Bzoj P2724 蒲公英


    Description

    Input

    修正一下

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

    Output

    HINT

    修正下:

    n <= 40000, m <= 50000

    题解

    • 就是要求区间众数,可以先离散化
    • 我们可以预处理f(i,j)表示第 i 块到第 j 块的众数

    • 那么只要能快速得出一个数在某个区间内出现次数即可,每次只要比较至多2√n+1个元素的出现次数

    • 由于没有修改,只要离散化以后,给每个数 x 开个vector,按顺序存下 x 出现的位置

    • 每次询问 x 时把区间的左右端点放进对应 vector 二分一下即可

    代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <map>
     5 #include <vector> 
     6 #include <algorithm>
     7 using namespace std;
     8 const int N=50010;
     9 int n,m,K=200,id,v[N],bl[N],f[510][510];
    10 map<int,int>mp;
    11 int val[N],cnt[N];
    12 vector<int>Q[N];
    13 int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    17     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 void pre(int x)
    21 {   
    22     memset(cnt,0,sizeof(cnt)); int mx=0,ans=0;
    23     for (int i=(x-1)*K+1;i<=n;i++)
    24     {       
    25         cnt[v[i]]++;        
    26         int t=bl[i];
    27         if (cnt[v[i]]>mx||(cnt[v[i]]==mx&&val[v[i]]<val[ans])) ans=v[i],mx=cnt[v[i]];
    28         f[x][t]=ans;
    29     }
    30 }
    31 int query(int l,int r,int x) { return upper_bound(Q[x].begin(),Q[x].end(),r)-lower_bound(Q[x].begin(),Q[x].end(),l); }
    32 int query(int a,int b)
    33 {
    34     int ans,mx;
    35     ans=f[bl[a]+1][bl[b]-1],mx=query(a,b,ans);
    36     for (int i=a;i<=min(bl[a]*K,b);i++)
    37     {
    38         int t=query(a,b,v[i]);
    39         if (t>mx||(t==mx&&val[v[i]]<val[ans])) ans=v[i],mx=t;
    40     }
    41     if (bl[a]!=bl[b])
    42         for (int i=(bl[b]-1)*K+1;i<=b;i++)
    43         {
    44             int t=query(a,b,v[i]);
    45             if (t>mx||(t==mx&&val[v[i]]<val[ans])) ans=v[i],mx=t;
    46         }
    47     return ans;
    48 }
    49 int main()
    50 {
    51     n=read(),m=read(); int ans=0;
    52     for (int i=1;i<=n;i++)
    53     {
    54         v[i]=read();
    55         if (!mp[v[i]]) mp[v[i]]=++id,val[id]=v[i];
    56         v[i]=mp[v[i]],Q[v[i]].push_back(i);
    57     }
    58     for (int i=1;i<=n;i++) bl[i]=(i-1)/K+1;
    59     for (int i=1;i<=bl[n];i++) pre(i);
    60     for (int a,b;m;m--)
    61     {
    62         a=read(),b=read();
    63         a=(a+ans-1)%n+1,b=(b+ans-1)%n+1;
    64         if (a>b) swap(a,b);
    65         printf("%d
    ",ans=val[query(a,b)]);
    66     } 
    67 }
  • 相关阅读:
    [CF1365D] Solve The Maze
    [CF478C] Table Decorations
    [CF466D] Increase Sequence
    [CF449D] Jzzhu and Numbers
    [CF507E] Breaking Good
    [CF337D] Book of Evil
    [CF1253E] Antenna Coverage
    VMware 在 Win10 下开机后死机的解决方案
    [CF1009F] Dominant Indices
    [CF1037E] Trips
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11211344.html
Copyright © 2020-2023  润新知