梦幻布丁——奇妙的线段树合并
作者:互联网
description
\(n\) 个布丁摆成一行,进行 \(m\) 次操作。每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色。
solution
线段树合并板子,用到动态开点.复杂度看似高,由于答案单调不增,所以实际上均摊下来只有\(\Omicron(n\log n)\)的复杂度.代码贴这里方便复习吧.
code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<ctime>
#define R register
#define next MabLcdG
#define mod 1
#define debug puts("mlg")
#define Mod(x) ((x%mod+mod)%mod)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writesp(ll x);
inline void writeln(ll x);
ll n,m;
const ll maxn=1e6;
struct Seg{
ll lc,rc,lv,rv,dat;
}t[maxn<<2];
ll rt[maxn];
ll cnt;
inline void update(ll p){
t[p].lv=t[p].lc?t[t[p].lc].lv:t[t[p].rc].lv;
t[p].rv=t[p].rc?t[t[p].rc].rv:t[t[p].lc].lv;
t[p].dat=t[t[p].lc].dat+t[t[p].rc].dat-(t[t[p].lc].rv+1==t[t[p].rc].lv);
}
inline void change(ll &p,ll l,ll r,ll x){
if(!p) p=++cnt;
if(l==r){t[p].lv=t[p].rv=x;t[p].dat=1;return;}
ll mid=l+r>>1;
if(x<=mid) change(t[p].lc,l,mid,x);
else change(t[p].rc,mid+1,r,x);
update(p);
}
inline void merge(ll &x,ll &y,ll l,ll r){
if(!x||!y){x+=y;return;}
if(l==r){t[x].lv=t[x].rv=l;t[x].dat=1;return;}
ll mid=l+r>>1;
merge(t[x].lc,t[y].lc,l,mid);
merge(t[x].rc,t[y].rc,mid+1,r);
update(x);
}
ll ans;
int main(){
n=read();m=read();
for(R ll i=1,x;i<=n;i++){
x=read();
ans-=t[rt[x]].dat;
change(rt[x],1,n,i);
ans+=t[rt[x]].dat;
}
while(m--){
ll op=read();
if(op==1){
ll x=read(),y=read();
if(x==y) continue;
ans-=t[rt[x]].dat;
ans-=t[rt[y]].dat;
merge(rt[y],rt[x],1,n);
rt[x]=0;
ans+=t[rt[y]].dat;
}
else{
writeln(ans);
}
}
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
inline void writesp(ll x){write(x);putchar(' ');}
inline void writeln(ll x){write(x);putchar('\n');}
标签:ll,布丁,梦幻,long,ch,mod,include,线段,define 来源: https://www.cnblogs.com/ylwtsq/p/13450195.html