「LibreOJ#516」DP 一般看规律
首先对于序列上一点,它对答案的贡献只有与它的前驱和后驱(前提颜色相同)构成的点对,
于是想到用set维护每个颜色,修改操作就是将2个set暴力合并(小的向大的合并),每次插入时更新答案即可
颜色数要离散化,或者用map也行
Code
#include <cstdio> #include <set> #include <map> #define N 100010 using namespace std; int n,m,Ans=2147483647; map<int,set<int>> A; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void upd(int c,int p){ auto it=A[c].lower_bound(p); if(it!=A[c].end()) Ans=min(Ans,(*it)-p); if(it!=A[c].begin()) --it,Ans=min(Ans,p-(*it)); A[c].insert(p); } int main(){ n=read(),m=read(); for(int i=1;i<=n;++i){int x=read();upd(x,i);} for(;m--;){ int x=read(),y=read(); if(x==y){printf("%d\n",Ans);continue;}//考虑特殊情况 if(A[x].size()>A[y].size()) swap(A[x],A[y]); for(int it:A[x]) upd(y,it); A[x].clear();//合并后应清空 printf("%d\n",Ans); } return 0; }