zoj 4089 Little Sub and Isomorphism Sequences

本题的意思是:给一个序列,有两种操作,第一个操作是修改某一个位置的值,第二个操作是询问整个序列中最长的两个不重合同构子串的长度。(同构的定义如题目所属,是字串中所有出现的数字,在两个子串中的出现次数都相同)

这道题还是想了很久,知道了答案就是相同数字的距离的最大值可是,不知道怎么维护,刚刚开始用线段树,结果太菜写不出来,后来看了大佬的代码,忽然知道了,用set储存每个数字出现的值,然后用multiset 保存每个数的最大距离,不能用set,因为同一距离的数可能有多个,如果用set在单点修改时会出错,最后需要注意在离散化时要把待修改的值一起离散化,然进行离线处理

在修改时,先把当前位置去除,更新去除后这个数的距离最大值,然后再把新的数加入,在进行更新。

代码如下:

///#include<bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
const int N=200010;
set<int>ss[N];
int a[N],x[N],c[N],y[N];
vector<int>v;
int getid(int x)
{
    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
int n,m;
multiset<int>mmp;
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        v.clear();
        mmp.clear();
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            v.push_back(a[i]);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&c[i]);
            if(c[i]==1)
            {
                scanf("%d%d",&x[i],&y[i]);
                v.push_back(y[i]);
            }
        }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        int cnt=v.size();
        for(int i=1;i<=cnt;i++)
        {
            ss[i].clear();
        }
        for(int i=1;i<=n;i++)
        {
            a[i]=getid(a[i]);
            ss[a[i]].insert(i);
        }
        for(int i=1;i<=cnt;i++)
        {
            if(!ss[i].empty())
                mmp.insert(*--ss[i].end()-*ss[i].begin());
        }
        for(int i=1;i<=m;i++)
        {
            if(c[i]==1)
            {
                int tmp=a[x[i]];
                mmp.erase(mmp.find(*--ss[tmp].end()-*ss[tmp].begin()));
                ss[tmp].erase(ss[tmp].find(x[i]));
                if(!ss[tmp].empty())
                    mmp.insert(*--ss[tmp].end()-*ss[tmp].begin());
                a[x[i]]=getid(y[i]);
                tmp=getid(y[i]);
                if(!ss[tmp].empty())
                    mmp.erase(mmp.find(*--ss[tmp].end()-*ss[tmp].begin()));
                ss[tmp].insert(x[i]);
                mmp.insert(*--ss[tmp].end()-*ss[tmp].begin());
            }
            else
            {
                int res=-1;
                if(!mmp.empty())
                {
                    res=*--mmp.end();
                }
                if(res==0)res=-1;
                printf("%d\n",res);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/KXL5180/article/details/87946525
今日推荐