daitangchen2008
2024-11-18 13:37:51
初始时每个位置看成一个单独的段,可发现,在染色的过程中段只会在端点颜色相同的时候变少,不会增加。
于是可以用 set 来维护整个过程。初始时放入每一个段的左端点,每次操作先二分出其所在的端点,然后暴力修改左右端点,并暴力判断是否能合并段,同时在这个过程中修改每个颜色的数量即可。
时间复杂度
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e5+10;
const int mod=998244353;
int a[N];
int mhash[N];
int siz[N];
string st;
set<int> s;
signed main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
s.insert(i);a[i]=i;
siz[i]=1;
}
s.insert(n+1);
int q;
cin>>q;
while(q--)
{
int opt,x,y;
cin>>opt>>x;
if(opt==2)
{
cout<<siz[x]<<endl;
continue;
}
cin>>y;
set<int>::iterator it =s.upper_bound(x);
it--;
int l=*it;
it++;
int r=*it;
r--;
it--;
int num=r-l+1;
siz[a[l]]-=num;
a[l]=y;
siz[a[l]]+=num;
a[r]=y;
if(l>=2)
{
if(a[l-1]==a[l])
s.erase(l);
}
if(r<n)
{
if(a[r]==a[r+1])
s.erase(r+1);
}
}
return 0;
}