P3939 数颜色
Posted garen-wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3939 数颜色相关的知识,希望对你有一定的参考价值。
数据结构学傻了吧!
这道题我一看上去:哦,数据结构。
再看上去:哦,分块题啊。
兴致冲冲地敲了个不熟练的分块,直接WA到只剩10pts。
过后很气地打了个暴力,60pts。。。
果然是暴力出奇迹啊!
不服气的我再打了个分块,终于写对了,却只有65pts,因为数据范围还是很大的,根号算法撑不住啦!
没错,就比暴力多5pts
正解是一个很玄的二分+vector。
对每一种颜色开一个vector,然后存入下标。
询问某种颜色的时候直接在这个vector里面upperbound和lowerbound两下就求出来了。
当然,这建立在首先sort过的情况。
不知道为什么,常数极小,一下就过了。。。
总结一下教训:
其实我在写那个分块的时候就已经跟暴力对拍过。并且数据生成器也一定不会出锅。
这个时候我的对拍一直停下来。
聪明人就应该知道我的分块已经写炸了,但我还以为我的generator搞错了。
最后还头铁地把分块交上去而不交一定对的暴力,最终GG。
故事告诉我们对拍的重要性和相信对拍的重要性!!!!
代码:
#include<cstdio>
#include<vector>
#include<algorithm>
const int maxn = 300005;
std::vector<int> vec[maxn];
int a[maxn];
int n, m;
int read()
{
int ans = 0, s = 1;
char ch = getchar();
while(ch > ‘9‘ || ch < ‘0‘){ if(ch == ‘-‘) s = -1; ch = getchar(); }
while(ch >= ‘0‘ && ch <= ‘9‘) ans = ans * 10 + ch - ‘0‘, ch = getchar();
return s * ans;
}
int main()
{
n = read(), m = read();
for(int i = 1; i <= n; i++)
{
a[i] = read();
vec[a[i]].push_back(i);
}
for(int i = 1; i <= n; i++) std::sort(vec[i].begin(), vec[i].end());
while(m--)
{
int opt = read();
if(opt == 1)
{
int l = read(), r = read(), c = read();
printf("%d
", std::upper_bound(vec[c].begin(), vec[c].end(), r) - std::lower_bound(vec[c].begin(), vec[c].end(), l));
}
else if(opt == 2)
{
int x = read();
if(a[x] != a[x + 1])
{
(*std::lower_bound(vec[a[x]].begin(), vec[a[x]].end(), x))++;
(*std::lower_bound(vec[a[x + 1]].begin(), vec[a[x + 1]].end(), x + 1))--;
std::swap(a[x], a[x + 1]);
}
}
}
return 0;
}
以上是关于P3939 数颜色的主要内容,如果未能解决你的问题,请参考以下文章