• [CF813E] Army Creation(分块,二分)


    题目链接:http://codeforces.com/contest/813/problem/E

    题意:n个人,每一个人有一个id。现在排成一排,现在要在n个人中的[l,r]区间内挑选,使得每一个id的出现次数不超过k。问每一个区间最多能选多少人。强制在线。

    学习了一个问题转化的巧妙思路,考虑每一个人不被统计的条件:这个人之前已经出现了k个人,并且这k个人出现在查询的区间内了。

    统计每一种id出现的位置i,每次更新与位置i出现的人id相同的前k+1个人的位置,假如没有则置-1,认为这个人没被删。

    按块更新,在块内排序。查询的时候就相当于查在某块内小于左端点值的数的个数。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef pair<int, int> pii;
     5 const int maxn = 100100;
     6 int n, k, q, sz;
     7 int a[maxn], pos[maxn], be[maxn];
     8 vector<int> b[maxn], G[maxn];
     9 
    10 int query(int l, int r) {
    11     int ret = 0;
    12     for(int i = l; i <= r; ) {
    13         if(i % sz == 0 && i + sz <= r) {
    14             ret += lower_bound(b[be[i]].begin(), b[be[i]].end(), l) - b[be[i]].begin();
    15             i += sz;
    16         }
    17         else if(pos[i++] < l) ret++;
    18     }
    19     return ret;
    20 }
    21 
    22 signed main() {
    23     // freopen("in", "r", stdin);
    24     int l, r;
    25     while(~scanf("%d%d",&n,&k)) {
    26         sz = sqrt(n);
    27         memset(pos, -1, sizeof(pos));
    28         for(int i = 0; i < n; i++) b[i].clear(), G[i].clear();
    29         for(int i = 0; i < n; i++) {
    30             scanf("%d", &a[i]);
    31             be[i] = i / sz;
    32             G[a[i]].push_back(i);
    33             if(G[a[i]].size() >= k + 1) pos[i] = G[a[i]][G[a[i]].size()-k-1];
    34             b[be[i]].push_back(pos[i]);
    35         }
    36         for(int i = 0; i <= n / sz; i++) sort(b[i].begin(), b[i].end());
    37         scanf("%d", &q);
    38         int ret = 0;
    39         while(q--) {
    40             scanf("%d%d",&l,&r);
    41             l = (l + ret) % n + 1;
    42             r = (r + ret) % n + 1;
    43             if(l > r) swap(l, r);
    44             printf("%d
    ", ret=query(--l, --r));
    45         }
    46     }
    47     return 0;
    48 }
  • 相关阅读:
    LVS 模式
    修改RocketMQ的NameServer端口
    一次清理Hbase的oldWALs的过程
    Linux下删除文件系统空间不释放的问题
    HBase 强制删除表
    关闭Found duplicated code
    Java操作HDFS代码样例
    RocketMQ:Cannot allocate memory
    Storm的StreamID使用样例(版本1.0.2)
    android studio 编译sdk版降低报错解决方法
  • 原文地址:https://www.cnblogs.com/kirai/p/7044380.html
Copyright © 2020-2023  润新知