bzoj2243 染色 樹鏈剖分 線段樹

2021-08-09 11:22:19 字數 1683 閱讀 8226

解題思路:

先鏈剖。

維護線段樹時每個節點維護三個值:lc(左端點顏色),rc(右端點顏色),cnt(區間中顏色段數量)。

注意每次合併區間時(詳見**中update,query,query函式),若左區間rc等於右區間lc是結果要減1;

修改時打標記即可,注意tag初始要賦值為-1,因為有color為0的情況。

#include

#include

#include

#include

#include

using namespace std;

int getint()

const int n=100005;

int n,m,a[n];

int ecnt,first[n],next[n<<1],to[n<<1];

int fa[n],dep[n],son[n],size[n],top[n],pos[n],idx[n];

int tot,cnt[n<<2],lc[n<<2],rc[n<<2],tag[n<<2];

void add(int

x,int

y)void dfs1(int u)

}void dfs2(int u)

for(int e=first[u];e;e=next[e])

}void update(int k)

void build(int k,int l,int r)

int mid=l+r>>1;

build(k<<1,l,mid),build(k<<1|1,mid+1,r);

update(k);

}void pushdown(int k)

void modify(int k,int l,int r,int

x,int

y,int c)

if(tag[k]!=-1)pushdown(k);

int mid=l+r>>1;

if(y

<=mid)modify(k<<1,l,mid,x,y,c);

else

if(x>mid)modify(k<<1|1,mid+1,r,x,y,c);

else modify(k<<1,l,mid,x,mid,c),modify(k<<1|1,mid+1,r,mid+1,y,c);

update(k);

}int find(int k,int l,int r,int p)

int query(int k,int l,int r,int

x,int

y)void modify(int u,int v,int c)

if(dep[u]>dep[v])swap(u,v);

modify(1,1,n,pos[u],pos[v],c);

}int query(int u,int v)

if(dep[u]>dep[v])swap(u,v);

res+=query(1,1,n,pos[u],pos[v]);

return res;

}int main()

dfs1(1);

tot=top[1]=pos[1]=idx[1]=1;

dfs2(1);

build(1,1,n);

while(m--)

else

}return

0;}

bzoj2243染色 樹鏈剖分 線段樹

time limit 20 sec memory limit 512 mb submit 8230 solved 3073 submit status discuss 給定一棵有 n個節點的無根樹和 m個操作,操作有2類 1 將節點 a到節點 b路徑上所有點都染成顏色c 2 詢問節點 a到節點 b路...

bzoj 2243 染色 樹鏈剖分

首先這是個挺裸的題,由於太久沒寫剖分導致調了好久,前天調了一下午,一直查不到錯 昨晚在看春晚的時候突然靈機一動,發現合併的時候出了問題,開電腦把它a掉了 感覺自己也蠻拼的給定 一棵有n 個節點的 無根樹和 m個操作 操作有 2類 1 將節點a 到節點b 路徑上所 有點都染 成顏色c 2 詢問節點a ...

bzoj 2243 樹鏈剖分 染色

time limit 20 sec memory limit 512 mb submit 3205 solved 1238 submit status discuss 給定一棵有n個節點的無根樹和m個操作,操作有2類 1 將節點a到節點b路徑上所有點都染成顏色c 2 詢問節點a到節點b路徑上的顏色段...