• BZOJ2120&&2453 数颜色&&维护队列


    2453: 维护队列

    Time Limit: 10 Sec Memory Limit: 128 MB
    Submit: 1442 Solved: 678
    [Submit][Status][Discuss]

    Description

    你小时候玩过弹珠吗?
    小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。

    Input

    输入文件第一行包含两个整数N和M。
    第二行N个整数,表示初始队列中弹珠的颜色。
    接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。

    Output

    对于每个Q操作,输出一行表示询问结果。

    Sample Input

    2 3

    1 2

    Q 1 2

    R 1 2

    Q 1 2

    Sample Output

    2

    1

    HINT

    对于100%的数据,有(1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000),小朋友A不会修改超过(1000)次,所有颜色均用(1)(10^6)的整数表示。

    题解

    待修改的莫队,对于每个询问,开三维(l),(r),(t),表示询问区间([l,r]),在第(t)次操作之后。先按(l)所在块排序,再按(r)所在块排序,再按(t)排序即可。
    执行的时候,先把修改时间定位,然后定位右端点,最后定位左端点。分块大小(n^frac{2}{3}),时间复杂度(O(n^frac{5}{3}))

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <cmath>
    #include <string>
    #define abs(x) ((x) < 0 ? -1 * (x) : (x))
    template <class T>
    inline void read(T &x)
    {
        x = 0;char ch = getchar(), c = ch;
        while(ch < '0' || ch > '9') c = ch, ch = getchar();
        while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
        if(c == '-') x = -x;
    }
    inline int max(int a, int b){return a > b ? a : b;}
    inline int min(int a, int b){return a < b ? a : b;}
    const int INF = 0x3f3f3f3f;
    const int MAXN = 1000000 + 10;
    int n,m,color[MAXN],p[MAXN],c[MAXN],last[MAXN],ctot,qtot,belong[MAXN],size;
    char s[100];
    struct Node
    {
    	int l, r, t, rank;
    }node[MAXN];
    bool cmp(Node a, Node b)
    {
    	return belong[a.l] == belong[b.l] ? (belong[a.r] == belong[b.r] ? a.t < b.t : belong[a.r] < belong[b.r]) : belong[a.l] < belong[b.l];
    }
    int l = 1, r = 0, now = 0, ans = 0, tong[MAXN], a[MAXN], pos[MAXN];
    void add(int x){ans += (++ tong[x]) == 1;}
    void del(int x){ans -= (-- tong[x]) == 0;}
    void change(int p, int c)
    {
    	if(l <= p && p <= r) add(c), del(color[p]);
    	color[p] = c;
    }
    int main()
    {
    	read(n), read(m);
    	for(int i = 1;i <= n;++ i) read(color[i]), tong[i] = color[i];
    	for(int i = 1;i <= m;++ i)
    	{
    		scanf("%s", s + 1);
    		if(s[1] == 'Q') ++ qtot, read(node[qtot].l), read(node[qtot].r), node[qtot].t = ctot, node[qtot].rank = qtot;
    		else if(s[1] == 'R') ++ ctot, read(p[ctot]), read(c[ctot]), last[ctot] = tong[p[ctot]], tong[p[ctot]] = c[ctot];
    	}
    	memset(tong, 0, sizeof(tong));
    	int size = pow(n, 0.66667);
    	for(int i = 1;i <= qtot;++ i)
    		if((i - 1) % size == 0) pos[i] = pos[i - 1] + 1;
    		else pos[i] = pos[i - 1];
    	std::sort(node + 1, node + 1 + qtot, cmp);
    	for(int i = 1;i <= qtot;++ i)
    	{
    		while(now < node[i].t) ++ now, change(p[now], c[now]);
    		while(now > node[i].t) change(p[now], last[now]), -- now;
    		while(r < node[i].r) ++ r, add(color[r]);
    		while(r > node[i].r) del(color[r]), -- r;
    		while(l < node[i].l) del(color[l]), ++ l;
    		while(l > node[i].l) -- l, add(color[l]);
    		a[node[i].rank] = ans;
    	}
    	for(int i = 1;i <= qtot;++ i) printf("%d
    ", a[i]);
    	return 0;
    }
    
  • 相关阅读:
    SqlServer无备份下误删数据恢复
    vue——storage命名冲突问题解决 前端
    vue——bus总线 前端
    elementUI——elform表单验证,表单项切换显示,校验错误信息未清除 前端
    elementUI——input输入框,设置autocomplete="off"无效问题 前端
    elementUI——table空单元格自动填充占位符,编辑后数据更新视图未更新问题 前端
    vue——爷孙组件之间通信 前端
    vue——路由守卫beforeEach,next(), next('/'), next({...to, repalce: true})说明及实例问题 前端
    elementUI——zindex自增问题 前端
    vue——vuecli3项目打包时区分环境以及环境变量undefined问题解决 前端
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8471403.html
Copyright © 2020-2023  润新知