zoukankan      html  css  js  c++  java
  • ZOJ

    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
    ",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;
    }
  • 相关阅读:
    [BNUOJ] ACM Battle(贪心)
    [BNUOJ]Training Plan(贪心,dp)
    [BNUOJ]Squared Permutation(线段树,单点更新)
    可以处理重边的求割点(边)模板
    [Python] Spark平台下实现分布式AC自动机(一)
    [HDOJ2222]Keywords Search(AC自动机)
    [GCJ] Qualification Round 2017
    HDU 6298.Maximum Multiple-数学思维题(脑子是个好东西,可惜我没有) (2018 Multi-University Training Contest 1 1001)
    牛客网 牛客小白月赛5 I.区间 (interval)-线段树 or 差分数组?
    牛客网 暑期ACM多校训练营(第二场)J.farm-STL(vector)+二维树状数组区间更新、单点查询 or 大暴力?
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10293407.html
Copyright © 2011-2022 走看看