Bzoj3531:[Sdoi2014]旅行:树链剖分+动态开点线段树

题目链接:[Sdoi2014]旅行

对于每种颜色维护一颗线段树,为了节约空间这里我们动态开点

然后就是弱鸡的线段树操作了

指针的动态开点线段树现在才会写……

#include
#include
#include
#include
using namespace std;
const int maxn=100010;
const int maxc=100001;
int n,m,tot=0,h[maxn],s[maxn],ind=0;
struct edge{int to,next;}G[maxn<<1];
int pos[maxn],Belong[maxn],dep[maxn];
int ret,w[maxn],c[maxn],fa[maxn];
char str[10];
struct seg{
	seg *lc,*rc;
	int s,mx;
	seg():lc(0x0),rc(0x0),s(0),mx(0){}
};
seg *root[maxn];

void add(int x,int y){
	G[++tot].to=y;G[tot].next=h[x];h[x]=tot;
}

void dfs1(int x){
	s[x]=1; dep[x]=dep[fa[x]]+1;
	for (int i=h[x];i;i=G[i].next){
		int v=G[i].to;
		if (v==fa[x]) continue;
		fa[v]=x; dfs1(v); s[x]+=s[v]; 
	}
}

void dfs2(int x,int L){
	pos[x]=++ind; int k=0; Belong[x]=L;
	for (int i=h[x];i;i=G[i].next)
		if (s[G[i].to]>s[k]&&dep[G[i].to]>dep[x]) k=G[i].to;
	if (!k) return; dfs2(k,L);
	for (int i=h[x];i;i=G[i].next)
		if (dep[G[i].to]>dep[x]&&k!=G[i].to) dfs2(G[i].to,G[i].to); 
}

void push_up(seg *p){
	p->s=p->mx=0;
	p->s+=p->lc?p->lc->s:0;
	p->s+=p->rc?p->rc->s:0;
	p->mx=p->lc?p->lc->mx:0;
	p->mx=max(p->mx,p->rc?p->rc->mx:0);
}

void update(seg *&p,int L,int R,int l,int r,int val){
	if (!p) p=new seg();
	if (l<=L&&R<=r){p->s=p->mx=val;return;}
	int mid=(L+R)>>1;
	if (llc,L,mid,l,r,val);
	if (midrc,mid,R,l,r,val);
	push_up(p);
}

void ask_mx(seg *p,int L,int R,int l,int r){
	if (!p) return;
	if (l<=L&&R<=r){ret=max(ret,p->mx);return;}
	int mid=(L+R)>>1;
	if (llc,L,mid,l,r);
	if (midrc,mid,R,l,r);
}

int query_mx(int x,int y,int col){
	int mx=0;
	while (Belong[x]!=Belong[y]){
		if (dep[Belong[x]]s;return;}
	int mid=(L+R)>>1;
	if (llc,L,mid,l,r);
	if (midrc,mid,R,l,r);
}

int query_s(int x,int y,int col){
	int ans=0;
	while (Belong[x]!=Belong[y]){
		if (dep[Belong[x]]


你可能感兴趣的:(OI,树链剖分,普通线段树)