题解:AT_abc380_e [ABC380E] 1D Bucket Tool

daitangchen2008

2024-11-18 13:37:51

Solution

分析

初始时每个位置看成一个单独的段,可发现,在染色的过程中段只会在端点颜色相同的时候变少,不会增加。
于是可以用 set 来维护整个过程。初始时放入每一个段的左端点,每次操作先二分出其所在的端点,然后暴力修改左右端点,并暴力判断是否能合并段,同时在这个过程中修改每个颜色的数量即可。
时间复杂度 O(Q\log n),可以通过。

代码

#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;
 }