• [CF813E]Army Creation


    题目大意:有$n$个数,$q$次询问,每次询问$[l,r]$中最多可以选多少个数使得相同的数最多有$k$个。($k$在同个测试点中相同)

    题解:$k$不变,可以预处理出每个数前面的第$k$个相同的数在哪,对于询问区间$[l,r]$,若前面的第$k$个数的位置小于$l$,则可以选择这个数。于是用主席树维护一段值域中数的个数即可

    卡点:

    C++ Code:

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    #define maxn 100010
    #define N (maxn * 20)
    std::vector<int> pos[maxn];
    int n, k, m;
    int rt[maxn], V[N], lc[N], rc[N], idx;
    
    void insert(int &rt, int l, int r, int num) {
    	lc[++idx] = lc[rt], rc[idx] = rc[rt], V[idx] = V[rt] + 1, rt = idx;
    	if (l == r) return ;
    	int mid = l + r >> 1;
    	if (num <= mid) insert(lc[rt], l, mid, num);
    	else insert(rc[rt], mid + 1, r, num);
    }
    int query(int L, int R, int l, int r, int num) {
    	if (r <= num) return V[R] - V[L];
    	int mid = l + r >> 1, ans = 0;
    	ans = query(lc[L], lc[R], l, mid, num);
    	if (num > mid) ans += query(rc[L], rc[R], mid + 1, r, num);
    	return ans;
    }
    
    int main() {
    	scanf("%d%d", &n, &k);
    	for (int i = 1, x; i <= n; i++) {
    		scanf("%d", &x);
    		pos[x].push_back(i);
    		int sz = pos[x].size();
    		if (sz > k) sz = pos[x][sz - k - 1];
    		else sz = 0;
    		rt[i] = rt[i - 1];
    		insert(rt[i], 0, n, sz);
    	}
    	scanf("%d", &m);
    	int last = 0;
    	while (m --> 0) {
    		int l, r;
    		scanf("%d%d", &l, &r);
    		l = (l + last) % n + 1, r = (r + last) % n + 1;
    		if (l > r) std::swap(l, r);
    		printf("%d
    ", last = query(rt[l - 1], rt[r], 0, n, l - 1));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    DELPHI开发LINUX包
    DELPHI开发LINUX的动态库
    中间件测试工具
    CENTOS7安装OPENSSL
    咏南跨平台中间件简介
    IdHTTPServer开发https服务器
    ServiceStack.Redis常用操作
    ServiceStack.Redis 之 IRedisTypedClient<第四篇>
    Redis常用命令速查 <第二篇>
    ServiceStack.Redis之IRedisClient<第三篇>
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9978777.html
Copyright © 2020-2023  润新知