隐藏
「fstqwq的2017/10/07模拟题」数颜色 - 二分+链表 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「fstqwq的2017/10/07模拟题」数颜色 - 二分+链表

题目大意





题目分析

本题不难会将人引入树套树、分块的巨坑中。

不过不难发现询问对颜色的处理相当单一,不难想到将颜色相同的兔子串成一个链表。

对于操作$1$,直接二分即可得到答案。
对于操作$2$,若$x$与$x+1$是同一个颜色,对链表无影响;若不是同一个颜色,虽然坐标发生了变化,但对于一个链表来说,相对关系并没有发生改变,因此不需要重构链表,暴力改掉坐标即可。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;

inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}

const int maxn=3*1e5+5;

int n,m,Max=0,a[maxn];
vector<int>Link[maxn];

int main() {
n=Get_Int();
m=Get_Int();
for(int i=1; i<=n; i++) {
int x=Get_Int();
Link[x].push_back(i);
a[i]=x;
Max=max(Max,x);
}
for(int i=1; i<=Max; i++) {
Link[i].push_back(0);
Link[i].push_back(n+1);
sort(Link[i].begin(),Link[i].end());
}
for(int i=1; i<=m; i++) {
int opt=Get_Int();
if(opt==1) {
int L=Get_Int(),R=Get_Int(),x=Get_Int();
auto l=lower_bound(Link[x].begin(),Link[x].end(),L),r=upper_bound(Link[x].begin(),Link[x].end(),R);
printf("%d\n",int(r-l));
} else {
int x=Get_Int(),y=x+1;
if(a[x]==a[y])continue;
auto pos1=lower_bound(Link[a[x]].begin(),Link[a[x]].end(),x),pos2=lower_bound(Link[a[y]].begin(),Link[a[y]].end(),y);
(*pos1)++;
(*pos2)--;
swap(a[x],a[y]);
}
}
return 0;
}

特别声明

本题解已获得$fstqwq$授权,原作者使用CC BY-NC-ND 4.0协议进行共享。
转载本套题请联系$fstqwq(QQ:849199382)$。

姥爷们赏瓶冰阔落吧~