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