zoukankan      html  css  js  c++  java
  • 【BZOJ】2724: [Violet 6]蒲公英

    2724: [Violet 6]蒲公英

    Time Limit: 40 Sec  Memory Limit: 512 MB
    Submit: 2900  Solved: 1031
    [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

    [Submit][Status][Discuss]


    HOME Back

    写的第一道分块题...结果几乎全都是照着$hzwer$写的QAQ,tcltcl...

    先离散化,维护块块之间的众数,用$vector$存每个颜色出现的每个位置,查询的时候在$vector$里面用$upper_bound$和$lower_bound$计算区间颜色数量,统计的时候,整个块答案先直接得到,块两边多余的元素暴力计算贡献,如果可以更优就更新。

    主要是注意分块中的一些细节,比如块的左闭右开(每次都要改很久aaa!!!),区间范围!还有就是不要再不小心把一个变量重新定义两次叻...QAQ

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    using namespace std;
    
    int n, m;
    ll a[50005], ls[50005], id[50005], cnt[50005];
    int blo, bl[50005], f[505][505];
    vector < int > vc[50005];
    
    void init ( int x ) {
        memset ( cnt, 0, sizeof ( cnt ) );
        int mx = 0, ans = 0;
        for ( int i = ( x - 1 ) * blo + 1; i <= n; i ++ ) {
            cnt[a[i]] ++;
            int t = bl[i];
            if ( cnt[a[i]] > mx || ( cnt[a[i]] == mx && id[ans] > id[a[i]] ) )
                mx = cnt[a[i]], ans = a[i];
            f[x][t] = ans;
        }
    }
    
    int query ( int l, int r, int x ) {
        int t = upper_bound ( vc[x].begin ( ), vc[x].end ( ), r ) - lower_bound ( vc[x].begin ( ), vc[x].end ( ), l );
        return t;
    }
    
    int query ( int l, int r ) {
        int ans, mx;
        ans = f[bl[l]+1][bl[r]-1];
        mx = query ( l, r, ans );
        for ( int i = l; i <= min ( bl[l] * blo, r ); i ++ ) {
            int t = query ( l, r, a[i] );
            if ( t > mx || ( t == mx && id[a[i]] < id[ans] ) )
                ans = a[i], mx = t;
        }
        if ( bl[l] != bl[r] )
            for ( int i = ( bl[r] - 1 ) * blo + 1; i <= r; i ++ ) {
                int t = query ( l, r, a[i] );
                if ( t > mx || ( t == mx && id[a[i]] < id[ans] ) )
                    ans = a[i], mx = t;
            }
        return ans;
    }
    
    int main ( ) {
        scanf ( "%d%d", &n, &m );
        blo = sqrt ( n );
        for ( int i = 1; i <= n; i ++ ) {
            scanf ( "%lld", &a[i] );
            ls[i] = a[i];
        }
        sort ( ls + 1, ls + 1 + n );
        int tot = unique ( ls + 1, ls + 1 + n ) - ls - 1;
        int s = 0;
        
        for ( int i = 1; i <= n; i ++ ) {
            int qwq = lower_bound ( ls + 1, ls + 1 + tot, a[i] ) - ls;
            vc[qwq].push_back ( i );
            id[qwq] = a[i];
            a[i] = qwq;
        }
        for ( int i = 1; i <= n; i ++ ) bl[i] = ( i + blo - 1 ) / blo;
        for ( int i = 1; i <= bl[n]; i ++ )    init ( i );
        int x = 0;
        for ( int i = 1; i <= m; i ++ ) {
            int l0, r0;
            scanf ( "%d%d", &l0, &r0 );
            int l = ( l0 + x - 1 ) % n + 1, r = ( r0 + x - 1 ) % n + 1;
            if ( l > r ) swap ( l, r );
            x = id[query ( l, r )];
            printf ( "%d
    ", x );
        }
        return 0;
    }
  • 相关阅读:
    机器学习-聚类问题
    机器学习--回归问题
    CreateRemoteThread盲注提权原理分析
    Linux下进程隐藏的方法及其对抗
    常见未授权访问漏洞总结
    Windows日志识别入侵痕迹
    打造自己的弱口令扫描工具
    Linux 命令被劫持,应急处理办法
    攻击Java Web应用--思维导图
    新型横向移动工具原理分析、代码分析、优缺点以及检测方案
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9544938.html
Copyright © 2011-2022 走看看