zoukankan      html  css  js  c++  java
  • Violet蒲公英

    传送门

    题目要求求出给定区间内编号最小的众数,强制在线。

    虽然说这是个黑题……不过我们可以用暴力分块解决它。首先先对所有数离散化,这个不影响众数。我们先预处理出每个数在前i个块内出现了多少次,再预处理出块i到块j内最小众数是谁。前者很好预处理,后者的话,我们只要固定i,之后向后枚举,每次新加入一个数的时候就比较出现最多次的元素来更新当前众数。如果到了块末尾,就更新块的答案。

    查询的时候,整块的我们直接去计算过的答案,之后对于每一个出现在零散位置的元素,我们记录下来,之后计算他们在整块中出现了多少次(前缀和相减即可),这样比较出出现次数最多的元素就可以。

    这题的处理稍微有点复杂,我的做法是开个栈来记录当前出现在零散位置的元素。

    看一下代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 40005;
    const int N = 205;
    const int INF = 1000000009;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    int n,m,B,a[M],l[N],r[N],sum[M][N],ans[N][N],x,y,last,b[M],cnt,blo[M],tot,g = 1,cur[M],maxx;
    int sta[M],top,mpos;
    
    void init()
    {
        rep(i,1,cnt)
        {
        rep(j,1,n) sum[j][i] += sum[j][i-1];
        rep(j,l[i],r[i]) sum[a[j]][i]++;
        }
        rep(i,1,cnt)
        {
        memset(cur,0,sizeof(cur)),maxx = mpos = 0,g = i;
        rep(j,l[i],n)
        {
            cur[a[j]]++;
            if(cur[a[j]] > maxx) maxx = cur[a[j]],mpos = a[j];
            else if(cur[a[j]] == maxx && a[j] < mpos) mpos = a[j];
            if(j == r[g]) ans[i][g] = mpos,g++;
        }
        }
    }    
    
    int query(int x,int y)
    {
        memset(cur,0,sizeof(cur)),maxx = mpos = 0;
        int L = blo[x],R = blo[y];
        if(L == R)
        {
        rep(i,x,y)
        {
            cur[a[i]]++;
            if(cur[a[i]] > maxx) maxx = cur[a[i]],mpos = a[i];
            else if(cur[a[i]] == maxx && a[i] < mpos) mpos = a[i]; 
        }
        return mpos;
        }
        int p = ans[L+1][R-1],now = sum[p][R-1] - sum[p][L];
        rep(i,x,r[L])
        {
        if(!cur[a[i]]) sta[++top] = a[i];
        cur[a[i]]++;
        }
        rep(i,l[R],y)
        {
        if(!cur[a[i]]) sta[++top] = a[i];
        cur[a[i]]++;
        }
        mpos = p;
        while(top)
        {
        int k = sta[top],q = sum[k][R-1] - sum[k][L] + cur[k];
        if(q > now) now = q,mpos = k;
        else if(q == now && k < mpos) mpos = k;
        top--;
        }
        return mpos;
    }
    
    int main()
    {
        n = read(),m = read(),B = sqrt(n);
        cnt = (n % B) ? n / B + 1 : n / B;
        rep(i,1,cnt) l[i] = r[i-1] + 1,r[i] = l[i] + B - 1;
        r[cnt] = n;
        rep(i,1,n) a[i] = b[i] = read();
        sort(b+1,b+1+n),tot = unique(b+1,b+1+n) - b - 1;
        rep(i,1,n) a[i] = lower_bound(b+1,b+1+tot,a[i]) - b;
        //rep(i,1,n) printf("%d ",a[i]);enter;
        rep(i,1,n)
        {
        blo[i] = g;
        if(i == r[g]) g++;
        }
        init();
        rep(i,1,m)
        {
        x = read(),y = read();
        x = (x + last - 1) % n + 1,y = (y + last - 1) % n + 1;
        if(x > y) swap(x,y);
        last = b[query(x,y)];
        printf("%d
    ",last);
        }
        return 0;
    }
  • 相关阅读:
    Photoshop 图文并茂常用快捷键
    程序员放松的8个好网站推荐
    Ehcache详细解读
    IT人士必去的10个网站
    [javascript]避免悲剧 密码生成器
    jQuery创建实例与原型继承揭秘
    [javascript]快速交换javascript变量的值
    [javascript]web216安全色拾色器colorpicker 支持浏览器边缘碰撞翻转(原生js)
    [Javascript]单例模式(singleton )
    duffsDevice 高速版
  • 原文地址:https://www.cnblogs.com/captain1/p/9841073.html
Copyright © 2011-2022 走看看