Time Limit: 3 Seconds
Memory Limit: 65536 KB
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:
;
Define
as the number of times integer
occur in sequence
. For each integer
in
,
always holds.
Now we have
operations for
. and there are two kinds of operations:
: Change
to
;
: Query for the greatest
that there exist two integers
and
and
is isomorphic with
. Specially, if there is no such
, please output “
” (without quotes) instead.
Input
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.
Output
For each operation 2, output one line containing the answer.
Sample Input
1
3 5
1 2 3
2
1 3 2
2
1 1 2
2
Sample Output
-1
1
2
题意:
给一个序列,有两个操作,第一个操作是单点修改,第二个操作是询问整个序列中最长的两个不重合同构子串的长度。(同构的定义是字串中所有出现的数字,在两个子串中的出现次数都相同)
题解:
我们可以发现,最长不重合同构子串肯定是相互重合的,只有两端是不重合的,那么我们只需要维护
中相同数字的最大距离
就可以了,答案就是
离散化,开20万个set,存数字
的位置信息,然后用线段树维护
,就可以了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#define LiangJiaJun main
using namespace std;
set<int>pos[200004];
map<int,int>mert;
int up;
int tr[800004],n,m;
struct als{
int x,lp;
}a[200004],A[100004];
struct mot{
int type,x,g,lp;
}work[100004];
inline bool dex(als X,als Y){
return X.x<Y.x;
}
void update(int x){
if(pos[x].size()<=1)tr[x+up]=-1;
else{
tr[x+up]=(*--pos[x].end())-(*pos[x].begin());
}
int now=x+up;now>>=1;
while(now>=1){
tr[now]=max(tr[now<<1],tr[now<<1|1]);
now>>=1;
}
}
int w33ha(){
mert.clear();
scanf("%d%d",&n,&m);
int cnt=n;
for(int i=1;i<=n;i++){
scanf("%d",&A[i].x);
a[i]=A[i];
}
for(int i=1;i<=m;i++){
scanf("%d",&work[i].type);
if(work[i].type==1){
scanf("%d%d",&work[i].g,&work[i].x);
a[++cnt].x=work[i].x;
}
}
sort(a+1,a+cnt+1,dex);
a[0].x=0;
int om=0;
for(int i=1;i<=cnt;i++){
if(a[i].x!=a[i-1].x){
mert[a[i].x]=++om;
a[i].lp=om;
pos[om].clear();
}
}
for(int i=1;i<=n;i++)A[i].lp=mert[A[i].x];
for(int i=1;i<=m;i++){
if(work[i].type==1)work[i].lp=mert[work[i].x];
}
for(int i=1;i<=n;i++){
pos[A[i].lp].insert(i);
}
up=1;
while(up<cnt+2)up<<=1;
for(int i=up;i>=1;i--){
tr[i<<1]=-1;
tr[i<<1|1]=-1;
}
for(int i=1;i<=cnt;i++){
if(pos[a[i].lp].size()<=1)tr[a[i].lp+up]=-1;
else{
tr[a[i].lp+up]=(*--pos[a[i].lp].end())-(*pos[a[i].lp].begin());
}
}
for(int i=up;i>=1;i--)tr[i]=max(tr[i<<1],tr[i<<1|1]);
for(int i=1;i<=m;i++){
if(work[i].type==1){
int g=work[i].g;
pos[A[g].lp].erase(g);
pos[work[i].lp].insert(g);
update(A[g].lp);
update(work[i].lp);
A[g].lp=work[i].lp;
A[g].x=work[i].x;
}
else{
printf("%d\n",tr[1]);
}
}
return 0;
}
int LiangJiaJun(){
int T;scanf("%d",&T);
while(T--)w33ha();
return 0;
}