zoukankan      html  css  js  c++  java
  • 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='
    ') {
    	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;
    }
    
  • 相关阅读:
    企业如何才能“勾搭”上服务网格技术?
    行云创新:云原生加速企业释放数据价值
    行云创新:后疫情时代,云原生为酒店数字化转型破局
    行云创新CEO马洪喜荣获“2021杰出质造人物奖”
    SolarMesh发布 v1.6.1版本,再不来体验就......
    什么是云原生?如何建设云原生平台?
    行云创新联合上汽乘用车打造云原生技术平台,加快实现数字化转型
    五分钟搭建你的第一个区块链应用
    mysql 存储过程
    MySQL-binlog日志格式 binlog_format三种模式详解
  • 原文地址:https://www.cnblogs.com/orchid-any/p/14668864.html
Copyright © 2011-2022 走看看