---
# System prepended metadata

title: tioj 1169 氣球博覽會

---

# tioj 1169 氣球博覽會

https://tioj.ck.tp.edu.tw/problems/1169

* 開$2^c$棵動態開點線段樹，每個代表區間不包含某顏色的最長長度
* 線段樹節點存從左邊，從右邊以及全部的最長不包含某顏色的長度，跟區間最大連續和一樣
    * 如果某節點是nullptr，代表全部都不包含那個顏色

```cpp=
#include <bits/stdc++.h>
#define pb push_back
#define F first
#define S second
#define rep(X, a,b) for(int X=a;X<b;++X)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) (int)(a).size()
#define NL "\n"
using namespace std;
typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef long long ll;

struct dat{
    ll pre=0;
    ll suf=0;
    ll mx=0;
};

struct tree{
    dat d;
    tree *left=nullptr;
    tree *right=nullptr;
}*root[(1<<24)+10];

tree* upd(tree *node, int l, int r, ll pos, int x){
    if(node==nullptr) node=new tree;
    if(l==r){
        node->d.pre=x;
        node->d.suf=x;
        node->d.mx=x;
        return node;
    }
    int mid=(l+r)>>1;
    if(pos<=mid) node->left=upd(node->left, l, mid, pos, x);
    else node->right=upd(node->right, mid+1, r, pos, x);

    dat a, b;
    if(node->left==nullptr) a={mid-l+1, mid-l+1, mid-l+1};
    else a=node->left->d;
    if(node->right==nullptr) b={r-mid, r-mid, r-mid};
    else b=node->right->d;
    node->d.mx=max(max(a.mx, b.mx), a.suf+b.pre);
    if(a.pre==mid-l+1) node->d.pre=a.pre+b.pre;
    else node->d.pre=a.pre;
    if(b.suf==r-mid) node->d.suf=a.suf+b.suf;
    else node->d.suf=b.suf;

    return node;
}

dat get(tree *node, int l, int r, int ql, int qr){
    if(ql<=l && qr>=r){
        if(node==nullptr) return {r-l+1, r-l+1, r-l+1};
        return node->d;
    }
    int mid=(l+r)>>1;
    if(qr<=mid) return get(node?node->left:nullptr, l, mid, ql, qr);
    else if(ql>mid) return get(node?node->right:nullptr, mid+1, r, ql, qr);
    else{
        dat a, b, res;
        a=get(node?node->left:nullptr, l, mid, ql, mid);
        b=get(node?node->right:nullptr, mid+1, r, mid+1, qr);
        res.mx=max(max(a.mx, b.mx), a.suf+b.pre);
        if(a.pre==mid-l+1) res.pre=a.pre+b.pre;
        else res.pre=a.pre;
        if(b.suf==r-mid) res.suf=a.suf+b.suf;
        else res.suf=b.suf;
        return res;
    }
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll n, q, c;
    cin>>n>>q>>c;
    ll k;
    vector<ll> num(n);
    rep(i,0,n){
        cin>>k;
        num[i]=k;
        root[k]=upd(root[k], 0, n-1, i, 0);
    }
    rep(i,0,q){
        int a;
        cin>>a;
        if(a==1){
            ll x, y, k;
            cin>>x>>y>>k;
            cout<<get(root[k], 0, n-1, x, y-1).mx<<NL;
        }
        else{
            ll p, k;
            cin>>p>>k;
            root[num[p]]=upd(root[num[p]], 0, n-1, p, 1);
            num[p]=k;
            root[k]=upd(root[k], 0, n-1, p, 0);
        }
    }
}
```