Solution -「YunoOI 2017」由乃的 OJ

Description

Link.

起床困难综合症 上树。

Solution

线段树维护,树剖上树。

具体题解有空再写,我要去睡觉了。

#include<bits/stdc++.h>
typedef unsigned long long ULL;
struct node {
	ULL one,zero;
	node(ULL A=0,ULL B=0) {
		one=A;
		zero=B;
	}
}nodes[400010],exnodes[400010],res,exres;
ULL poi[100010],opz;
int k,dep[100010],son[100010],hb[100010],fa[100010],dfn[100010],sjc,op[100010],n,m,rev[100010],siz[100010];
int head[100010],nxt[200010],to[200010],cntot,opt,opx,opy;
bool flag,exflag;
void addEdge(int one,int ano) {
	to[++cntot]=ano;
	nxt[cntot]=head[one];
	head[one]=cntot;
}
node merge(node one,node ano) {
	node res(~0ull);
	ULL tmp=one.one,extmp=~tmp;
	res.one=(tmp&ano.one)|(extmp&ano.zero);
	tmp=one.zero;
	extmp=~tmp;
	res.zero=(tmp&ano.one)|(extmp&ano.zero);
	return res;
}
void adj(ULL &x,ULL y,int id) {
	if(id==1) {
		x&=y;
	} else if(id==2) {
		x|=y;
	} else {
		x^=y;
	}
}
void build(int l,int r,int x) {
	if(l^r) {
		int mid=(l+r)>>1;
		build(l,mid,x<<1);
		build(mid+1,r,x<<1|1);
		nodes[x]=merge(nodes[x<<1],nodes[x<<1|1]);
		exnodes[x]=merge(exnodes[x<<1|1],exnodes[x<<1]);
	} else {
		nodes[x]=exnodes[x]=node(~0ull);
		adj(nodes[x].one,poi[rev[l]],op[rev[l]]);
		adj(nodes[x].zero,poi[rev[l]],op[rev[l]]);
		adj(exnodes[x].one,poi[rev[l]],op[rev[l]]);
		adj(exnodes[x].zero,poi[rev[l]],op[rev[l]]);
	}
}
void ins(int l,int r,int x,int pos,int aj,ULL val) {
	if(l^r) {
		int mid=(l+r)>>1;
		if(mid>=pos) {
			ins(l,mid,x<<1,pos,aj,val);
		} else {
			ins(mid+1,r,x<<1|1,pos,aj,val);
		}
		nodes[x]=merge(nodes[x<<1],nodes[x<<1|1]);
		exnodes[x]=merge(exnodes[x<<1|1],exnodes[x<<1]);
	} else {
		op[rev[l]]=aj;
		poi[rev[l]]=val;
		nodes[x]=exnodes[x]=node(~0ull);
		adj(nodes[x].one,poi[rev[l]],op[rev[l]]);
		adj(nodes[x].zero,poi[rev[l]],op[rev[l]]);
		adj(exnodes[x].one,poi[rev[l]],op[rev[l]]);
		adj(exnodes[x].zero,poi[rev[l]],op[rev[l]]);
	}
}
void find(int l,int r,int x,int fr,int ba) {
	if(l>ba || r<fr) {
		return;
	} else {
		if(l>=fr && r<=ba) {
			if(!flag) {
				res=nodes[x];
				flag=true;
			} else {
				res=merge(nodes[x],res);
			}
		} else {
			int mid=(l+r)>>1;
			find(mid+1,r,x<<1|1,fr,ba);
			find(l,mid,x<<1,fr,ba);
		}
	}
}
void exfind(int l,int r,int x,int fr,int ba) {
	if(l>ba || r<fr) {
		return;
	} else {
		if(l>=fr && r<=ba) {
			if(!exflag) {
				exres=exnodes[x];
				exflag=true;
			} else {
				exres=merge(exres,exnodes[x]);
			}
		} else {
			int mid=(l+r)>>1;
			exfind(mid+1,r,x<<1|1,fr,ba);
			exfind(l,mid,x<<1,fr,ba);
		}
	}
}
node LCA(int x,int y) {
	flag=exflag=false;
	res=exres=node(~0ull);
	while(hb[x]^hb[y]) {
		if(dep[hb[x]]>dep[hb[y]]) {
			exfind(1,n,1,dfn[hb[x]],dfn[x]);
			x=fa[hb[x]];
		} else {
			find(1,n,1,dfn[hb[y]],dfn[y]);
			y=fa[hb[y]];
		}
	}
	if(dep[x]<dep[y]) {
		find(1,n,1,dfn[x],dfn[y]);
	} else {
		exfind(1,n,1,dfn[y],dfn[x]);
	}
	return merge(exres,res);
}
void dfs1(int x,int las) {
	dep[x]=dep[las]+1;
	fa[x]=las;
	siz[x]=1;
	for(int i=head[x];i;i=nxt[i]) {
		int y=to[i];
		if(y^las) {
			dfs1(y,x);
			siz[x]+=siz[y];
			if(siz[son[x]]<siz[y]) {
				son[x]=y;
			}
		}
	}
}
void dfs2(int x,int t) {
	hb[x]=t;
	dfn[x]=++sjc;
	rev[sjc]=x;
	if(son[x]) {
		dfs2(son[x],t);
		for(int i=head[x];i;i=nxt[i]) {
			int y=to[i];
			if((y^fa[x]) && (y^son[x])) {
				dfs2(y,y);
			}
		}
	}
}
ULL solve(node now,ULL lim) {
	ULL res=0,run=0;
	for(int i=k-1;~i;--i) {
		if(now.zero&(1ull<<i)) {
			res+=(1ull<<i);
		} else if((now.one&(1ull<<i)) && run+(1ull<<i)<=lim) {
			run+=(1ull<<i);
			res+=(1ull<<i);
		}
	} 
	return res;
}
char fgc() {
	static char buf[1<<21],*p=buf,*q=buf;
	return p==q && (q=buf+fread(p=buf,1,1<<21,stdin),p==q)?EOF:*p++;
}
template<typename T>
void read(T &hhh) {
	T x=0;
	int f=0;
	char c=fgc();
	while(c<'0' || c>'9') {
		if(c=='-') {
			f=1;
		}
		c=fgc();
	}
	while(c>='0' && c<='9') {
		x=(x<<3)+(x<<1)+(c^'0');
		c=fgc();
	}
	if(f) {
		hhh=-x;
	} else {
		hhh=x;
	}
}
int wrstk[100];
template<typename T>
void write(T x,char las='\n') {
	int top=0,f=0;
	if(x<0) {
		x=-x;
		f=1;
	}
	do {
		wrstk[++top]=x%10;
		x/=10;
	} while(x);
	if(f) {
		putchar('-');
	}
	while(top) {
		putchar(wrstk[top--]^'0');
	}
	putchar(las);
}
int main() {
	read(n);
	read(m);
	read(k);
	for(int i=1;i<=n;++i) {
		read(op[i]);
		read(poi[i]);
	}
	for(int i=1,x,y;i<n;++i) {
		read(x);
		read(y);
		addEdge(x,y);
		addEdge(y,x);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,n,1);
	while(m-->0) {
		read(opt);
		read(opx);
		read(opy);
		read(opz);
		if(opt==1) {
			if(k) {
				write(solve(LCA(opx,opy),opz));
			} else {
				write(0);
			}
		} else {
			ins(1,n,1,dfn[opx],opy,opz);
		}
	}
	return 0;
}
posted @ 2021-04-16 21:41  cirnovsky  阅读(73)  评论(0编辑  收藏  举报