• luoguP3939 数颜色


    传送门

    题解

    懒得写题,又不想颓,所以开始水题解。

    大意就是维护一个序列,要求支持两种操作:一是在给出的区间内查询某个值的出现次数,二是交换相邻某两个的元素。

    一看到区间操作就想到了线段树...于是开始打主席树,打到一半发现不会打...又改成普通线段树,打完后发现比暴力还慢上好几倍...主要是颜色可能有很多种,而且相当分散,线段树的区间效果体现不出来...

    然后这道题还很是毒瘤地卡了主席树,ST表...甚至它连分块都卡了...(出题人这样恶意满满不会折阳寿吗)

    于是,面对3e5的数据,数据结构已经GG了,还有什么能够拯救我们呢?没错,那就是我们的STL!(STL大法好)(然鹅上一题的lower_bound就被卡飞了)

    因为颜色的种类很多,分布又很稀疏,用数组来存储是不可能的,但是,我们有伟大的(vector)

    直接反手开一个vector,(vector[i])表示(i)这个颜色依次出现的下标,就算你数据再怎么毒瘤,只要我动态开内存不就好了吗,反正就算是由于(vector)的特性它最多也就6e5的内存,完全够了。另外由于我们在读入时直接记录,所以它一定是满足单调上升的,所以在查找时可以二分优化一下。

    具体的实现参见代码吧。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    char buf[1 << 20], *p1, *p2;
    char getc() {
    	if(p1 == p2) {
    		p1 = buf;
    		p2 = buf + fread(buf, 1, 1 << 20, stdin);
    		if(p1 == p2) return EOF;
    	}
    	return *p1++;
    }
    inline ll read() {
    	ll s = 0, w = 1; char c = getc();
    	while(c < '0' || c >'9') {if(c == '-')w = -1; c = getc();}
    	while(c >= '0' && c <= '9') s = s * 10 + c - '0', c = getc();
    	return s * w;
    }
    const int maxn = 3e5 + 100;
    int n, m;
    int a[maxn];
    vector<int> col[maxn];
    int main() {
    	n = read(), m = read();
    	for(register int i = 1; i <= n; i++) {
    		a[i] = read();
    		col[a[i]].push_back(i);
    	}
    	int op, x, y, z;
    	int it1, it2;
    	for(register int i = 1; i <= m; i++) {
    		op =  read();
    		if(op == 1) {
    			x = read(), y = read(), z = read();
    			it1 = lower_bound(col[z].begin(), col[z].end(), x) - col[z].begin();
    			it2 = upper_bound(col[z].begin(), col[z].end(), y) - 1 - col[z].begin();
    			printf("%d
    ", it2 - it1 + 1);
    		}
    		else {
    			x = read();
    			if(a[x] == a[x + 1]) continue;
    			it1 = lower_bound(col[a[x]].begin(), col[a[x]].end(), x) - col[a[x]].begin();
    			col[a[x]][it1]++;
    			it2 = lower_bound(col[a[x + 1]].begin(), col[a[x + 1]].end(), x + 1) - col[a[x + 1]].begin();
    			col[a[x + 1]][it2]--;
    			swap(a[x], a[x + 1]);
    		}
    	}
    }
    
  • 相关阅读:
    js 复杂研究
    js 页面 保持状态 的方法
    C# 向上取整数
    js 获取dom 为null 测试
    net core 下 接受文件 测试
    layui 源码解读(部分)
    js 定时器
    js addEventListener
    C# 获得对象的命名空间 ?.
    修改maven的默认jdk版本
  • 原文地址:https://www.cnblogs.com/Zfio/p/13428086.html
Copyright © 2020-2023  润新知