1. 程式人生 > >ZOJ - 4089 :Little Sub and Isomorphism Sequences (同構 set)

ZOJ - 4089 :Little Sub and Isomorphism Sequences (同構 set)

names 最長 namespace zoj opera 修改 fine code 每次

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:

  1. ;
  2. 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:

  • 1 x y: Change to (, );
  • 2: Query for the greatest () that there exist two integers and () and is isomorphic with . Specially, if there is no such , please output "-1" (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

題意:給定你個數組,以及一些單點修改,以及詢問,每次詢問需要求得,最長的字串長度,它在其他位置存在同構。

思路:最長同構子串對總是會重疊的,然後兩個子串不重疊的部分必須是同構。 那麽一定有,最優之一就是“x+公共”與“公共+x”這兩個同構最長。

這個不難反證。 那麽實現就是每種樹建立set,然後保存每個set的最遠距離即可。

#include<bits/stdc++.h>
#define rep(i,w,v) for(int i=w;i<=v;i++)
using namespace std;
const int maxn=200010;
int a[maxn],b[maxn],c[maxn],x[maxn],y[maxn],tot;
set<int>s[maxn];
multiset<int>S;
multiset<int>::iterator it;
int main()
{
    int T,N,M,ans;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M); tot=0;
        rep(i,1,N) scanf("%d",&a[i]),b[++tot]=a[i];
        rep(i,1,M){
            scanf("%d",&c[i]);
            if(c[i]==1) {
                scanf("%d%d",&x[i],&y[i]);
                b[++tot]=y[i];
            }
        }
        sort(b+1,b+tot+1);
        tot=unique(b+1,b+tot+1)-(b+1);
        S.clear(); rep(i,1,tot) s[i].clear();
        rep(i,1,N) {
            a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
            s[a[i]].insert(i);
        }
        rep(i,1,tot) if(!s[i].empty())
          S.insert(*(--s[i].end())-*s[i].begin());
        rep(i,1,M){
            if(c[i]==2){
                ans=-1;
                if(!S.empty()) ans=*(--S.end());
                if(ans==0) ans=-1;
                printf("%d\n",ans);
            }
            else {
                it=S.find(*(--s[a[x[i]]].end())-*s[a[x[i]]].begin());
                s[a[x[i]]].erase(x[i]);
                S.erase(it);
                if(!s[a[x[i]]].empty()) S.insert(*(--s[a[x[i]]].end())-*s[a[x[i]]].begin());

                y[i]=lower_bound(b+1,b+tot+1,y[i])-b; a[x[i]]=y[i];
                if(!s[y[i]].empty())  S.erase(S.find(*(--s[y[i]].end())-*s[y[i]].begin()));
                s[y[i]].insert(x[i]);
                S.insert(*(--s[y[i]].end())-*s[y[i]].begin());
            }
        }
    }
    return 0;
}

ZOJ - 4089 :Little Sub and Isomorphism Sequences (同構 set)