zoukankan      html  css  js  c++  java
  • 【BZOJ 2714】蒲公英

    https://blog.csdn.net/nixinyis/article/details/68075234?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1

    给一个序列,求一个区间的众数。(强制在线)

    Sol:

    先分块。
    设f[i][j]表示第i块到第j块总的众数
    然后每次对于一个询问[l,r],x到y已经知晓,
    答案只可能是l~x,y~r,和块x~y的众数之一,
    所以接下来要做的就是判断l~x和y~r中存不存在数字出现次数比块x到y众数出现更多的数。
    不过怎么判断呢?可以先用vector来保存每个数字出现的位置
    (因为本题的值域较大,所以要离散化一下,就是map来搞一搞),
    在用二分答案查找这个数字在[l,r]内出现的次数即可

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #define N 40010
    #define B 200
    using namespace std;
    map<int,int> mp;
    vector<int> pos[N];
    int cnt,val[N],a[N];
    int belong[N],tot[N],f[B+5][B+5];
    int n;
    void pre(int x)
    {
        int now = 0,maxnsum = 0;
        memset(tot,0,sizeof(tot));
        for(int i = (x-1)*B + 1;i <= n;i++) 
    	{
            tot[a[i]] ++;
            if(tot[a[i]] > maxnsum || (tot[a[i]] == maxnsum && val[now] > val[a[i]]) )
                now = a[i],maxnsum = tot[a[i]];
            f[x][belong[i]] = now;
            //f[i][j]表示第i块到第j块总的众数
        }
    }
    
    int sigma(int l,int r,int x) 
    {
        return upper_bound(pos[x].begin(),pos[x].end(),r)-lower_bound(pos[x].begin(),pos[x].end(),l);
    }
    
    int query(int l,int r)
    {
        int now = f[belong[l]+1][belong[r]-1],maxnsum = sigma(l,r,now);
        for(int i = l;i <= min(r,belong[l]*B);i++)
    	//左边区间 [l,min(r,belong[l]*B)
    	{
            int tmp = sigma(l,r,a[i]);
            if(tmp > maxnsum || (tmp == maxnsum && val[now] > val[a[i]]) )
                now = a[i],maxnsum = tmp;
        }
        if(belong[l] != belong[r]) 
    	{
            for(int i = (belong[r]-1)*B+1;i <= r;i++) 
            //左边区间 [(belong[r]-1)*B+1,r]
    		{
                int tmp = sigma(l,r,a[i]);
                if(tmp > maxnsum || (tmp == maxnsum && val[now] > val[a[i]]) )
                    now = a[i],maxnsum = tmp;
            }
        }
        return now;
    }
    
    int main()
    {
        int m,l,r;
        int ans = cnt = 0;
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++) 
    	{
            scanf("%d",&a[i]);
            if(!mp[a[i]]) 
    		{
                mp[a[i]] = ++cnt; 
    			val[cnt] = a[i];
            }
            a[i] = mp[a[i]];
            pos[a[i]].push_back(i);
        }
        for(int i = 1;i <= n;i++) 
    	    belong[i] = (i-1)/B + 1;
        for(int i = 1;i <= belong[n];i++) 
    	    pre(i);
    
        for(int i = 1;i <= m;i++) 
    	{
            scanf("%d%d",&l,&r);
            l = (l+ans-1) % n + 1; r = (r+ans-1) % n + 1;
            if(l > r) swap(l,r);
            ans = val[query(l,r)];
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Could A New Linux Base For Tablets/Smartphones Succeed In 2017?
    使用libhybris,glibc和bionic共存时的TLS冲突的问题
    6 Open Source Mobile OS Alternatives To Android in 2018
    Using MultiROM
    GPU drivers are written by the GPU IP vendors and they only provide Android drivers
    Jolla Brings Wayland Atop Android GPU Drivers
    How to Use Libhybris and Android GPU Libraries with Mer (Linux) on the Cubieboard
    闲聊Libhybris
    【ARM-Linux开发】wayland和weston的介绍
    Wayland and X.org problem : Why not following the Android Solution ?
  • 原文地址:https://www.cnblogs.com/cutemush/p/12795048.html
Copyright © 2011-2022 走看看