标签:names 有序 条件 传送门 red pre get des lan
传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5868
Little Sub has a sequence . Now he has a problem for you.
Two sequences of length and of length are considered isomorphic when they meet all the following two conditions:
Now we have operations for . and there are two kinds of operations:
There are multiple test cases. The first line of the input contains an integer (), indicating the number of test cases. For each test case:
The first line ontains two integers .
The second line contains integers ().
In the following lines, each line contains one operation. The format is described above.
For each operation 2, output one line containing the answer.
1 3 5 1 2 3 2 1 3 2 2 1 1 2 2
-1 1 2
给出 一个长度为 N 的序列, 和 M 次操作.
有两种操作:
1 id y : 把序列中第 id 个位置的值 修改成 y
2 : 查询这个序列中能满足两个子串“相同”的最大长度。
两个子串相同的条件:子串的数字种类和每种种类的数量相同,当然两个子串的起点不同(理所当然,否则这道题就没意义了)。
很明显就是维护每种 相同的值的 下标(位置)的 最大差值。
因为除了两端的值,中间公共部分 无论是数量还是种类肯定相同。
那么问题就转换成了如何维护每种值 value 的位置最大差值。
用 set 存每种 value 的下标,最多需要 20w个(最坏的情况就是每次操作都是插入新的值)
用 multiset 维护 最大差值。
值 val 的范围是 【1, 1e9】,需要离散化。
在线 map 离散化 RE。
离线 lower_bound() AC。
AC code:
1 #include <set> 2 #include <map> 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 #define INF 0x3f3f3f3f 8 #define LL long long 9 using namespace std; 10 const int MAXN = 2e5+10; 11 const int MAXM = 2e5+10; 12 int a[MAXN]; //存实际序列 13 int b[MAXN]; //存所有序列包括原序列的值和修改的值,用于离散化 14 int c[MAXN]; //存操作 15 int x[MAXN]; //存修改的下标 16 int y[MAXN]; //存修改的值 17 set<int>ss[MAXM]; ///维护每一种值的起点和终点 18 multiset<int>ans; ///维护两点距离差 19 //map<int, int>mmp; 20 int N, M; 21 22 int main() 23 { 24 int cnt = 0; 25 int T_case; 26 scanf("%d", &T_case); 27 while(T_case--){ 28 29 int cnt = 0; 30 ans.clear(); 31 scanf("%d %d", &N, &M); 32 for(int i = 1; i <= N; i++){ 33 scanf("%d", &a[i]); 34 b[++cnt] = a[i]; 35 } 36 37 for(int i = 1; i <= M; i++){ 38 scanf("%d", &c[i]); 39 if(c[i] == 1){ 40 scanf("%d %d",&x[i], &y[i]); 41 b[++cnt] = y[i]; 42 } 43 } 44 sort(b+1, b+1+cnt); 45 cnt = unique(b+1, b+cnt+1)-(b+1); ///离散化后的数据总量 46 47 for(int i = 1; i <= cnt; i++){ ///初始化 48 ss[i].clear(); 49 } 50 51 for(int i = 1; i <= N; i++){ 52 a[i] = lower_bound(b+1, b+cnt+1, a[i])-b; ///对原序列的值进行离散化 53 ss[a[i]].insert(i); 54 } 55 56 for(int i = 1; i <= cnt; i++){ 57 if(!ss[i].empty()) ans.insert(*--ss[i].end() - *ss[i].begin()); ///初始化两点距离差 58 } 59 60 for(int i = 1; i <= M; i++){ 61 if(c[i] == 1){ ///删除操作 62 int no = a[x[i]]; 63 ans.erase(ans.find( *--ss[no].end()-*ss[no].begin()) ); 64 ss[no].erase(ss[no].find(x[i])); 65 if(!ss[no].empty()) ans.insert(*--ss[no].end()-*ss[no].begin()); 66 67 68 y[i] = lower_bound(b+1, b+cnt+1, y[i])-b; ///增加操作 69 a[x[i]] = y[i]; 70 no = y[i]; 71 if(!ss[no].empty()) ans.erase(ans.find( *--ss[no].end()-*ss[no].begin()) ); 72 ss[no].insert(x[i]); 73 ans.insert(*--ss[no].end()-*ss[no].begin()); 74 } 75 else{ 76 int res = -1; 77 if(!ans.empty()){ 78 res = *--ans.end(); 79 } 80 if(res == 0) res = -1; 81 printf("%d\n", res); 82 } 83 } 84 85 86 } 87 return 0; 88 }
ZOJ Monthly, January 2019 Little Sub and Isomorphism Sequences 【离线离散化 + set + multiset】
标签:names 有序 条件 传送门 red pre get des lan
原文地址:https://www.cnblogs.com/ymzjj/p/10294710.html