zoukankan      html  css  js  c++  java
  • [国家集训队]数颜色 / 维护队列 (带修改莫队)

    题目链接

    题解

    树套树做法暂时不会,先坑着

    带修改的莫队

    在普通莫队基础上加一个时间量

    修改时调整区间,同时调整时间

    具体看代码

    Code

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    
    const int N = 2000010, M = 50010;
    
    int n, m, C[N], belong[N];
    
    struct qus {
    	int l, r, id, tim;//tim记录在这次询问之前最近它的修改
    	bool operator <(qus z) const {
    		if (belong[l] == belong[z.l]) {
    			if (belong[r] == belong[z.r])
    				return tim < z.tim;
    			return r < z.r;
    		}
    		return l < z.l;
    	}
    }q[M];
    struct node {
    	int pos, v;
    }o[M];
    
    //o记录修改操作,q记录询问
    int cnt1, cnt2;
    
    int tot[N], ans, a[M];
    
    inline void del(int c) {if(!(--tot[c])) ans--;}//删掉
    inline void add(int c) {if(++tot[c] == 1) ans++;}//添加
    inline void change(int now, int k) {
    	if (q[k].l <= o[now].pos && o[now].pos <= q[k].r)
    		del(C[o[now].pos]), add(o[now].v);
    	swap(C[o[now].pos], o[now].v);//这里是交换,因为后面撤销操作需要掉换回来
    	return ;
    }
    
    inline int gi() {
    	RG int x = 0; RG char c = getchar(); bool f = 0;
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') c = getchar(), f = 1;
    	while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
    	return f ? -x : x;
    }
    
    int main() {
    	int n = gi(), m = gi(), siz = pow(n, 0.666666666666);//siz为块的大小
    	for (RG int i = 1; i <= n; i++) C[i] = gi(), belong[i] = (i-1)/siz+1;
    	char type;
    	while (m--) {
    		scanf("
    %c", &type);
    		if (type == 'Q') {
    			q[++cnt1].l = gi(); q[cnt1].r = gi(); q[cnt1].id = cnt1; q[cnt1].tim = cnt2;
    		}
    		else o[++cnt2].pos = gi(), o[cnt2].v = gi();		
    	}
    	sort(q+1, q+1+cnt1);
    	int l = 1, r = 0, now = 0;
    	for (int i = 1; i <= cnt1; i++) {
    		while (l > q[i].l) add(C[--l]);
    		while (l < q[i].l) del(C[l++]);
    		while (r < q[i].r) add(C[++r]);
    		while (r > q[i].r) del(C[r--]);
    		while (now < q[i].tim) change(++now, i);
    		while (now > q[i].tim) change(now--, i);
    		a[q[i].id] = ans;
    	}
    	for (int i = 1; i <= cnt1; i++)
    		printf("%d
    ", a[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    windows10使用arcgis注意事项
    andriod arcgis加载影像TIF
    FeatureTable()
    arcgis Listview
    ArcGIS for Android图层记录数,图层选择记录,图层字段数
    ArcGIS for Android 点击选择
    ArcGIS for Android地图上实际距离与对应的屏幕像素值计算
    Android如何检查对象的类型
    北美内地电影票房总排行榜
    XSS漏洞的渗透利用另类玩法
  • 原文地址:https://www.cnblogs.com/zzy2005/p/10135980.html
Copyright © 2011-2022 走看看