首页 > 其他分享 >【做题记录】CodeForces343D Water Tree

【做题记录】CodeForces343D Water Tree

时间:2023-05-19 23:12:03浏览次数:57  
标签:int CodeForces343D void NUMBER1 Tree Water odt qrw id

题面翻译

  • 给出一棵以 \(1\) 为根节点的 \(n\) 个节点的有根树。每个点有一个权值,初始为 \(0\)。
  • \(m\) 次操作。操作有 \(3\) 种:
    1. 将点 \(u\) 和其子树上的所有节点的权值改为 \(1\)。
    2. 将点 \(u\) 到 \(1\) 的路径上的所有节点的权值改为 \(0\)。
    3. 询问点 \(u\) 的权值。
  • \(1\le n,m\le 5\times 10^5\)。

所以说这可以用树链剖分来解决。
至于 2 、 3 操作,可以用线段树来维护(满足加法交换律的似乎都可以考虑线段树),但我不想写线段树,于是写了珂朵莉树 ODT (明显码量小了很多,但时间慢了很多)。

代码:

#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<set>
#include<algorithm>
typedef long long LL;
typedef unsigned long long ULL;
namespace FastIo{
    static char buf[100000],*p1=buf,*p2=buf,fw[100000],*pw=fw;
    #define gc p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++
    inline void pc(const char &ch){
    	if(pw-fw==100000)fwrite(fw,1,100000,stdout),pw=fw;
    	*pw++=ch;
	}
    #define fsh fwrite(fw,1,pw-fw,stdout),pw=fw
    struct QIO{
    	char ch;
    	int st[40];
    	template<class T>inline void read(T &x){
    		x=0,ch=gc;
    		while(!isdigit(ch))ch=gc;
    		while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=gc;}
		}
		template<class T>inline void write(T a){
			do{st[++st[0]]=a%10;a/=10;}while(a);
			while(st[0])pc(st[st[0]--]^48);
			pc('\n');
		}
	}qrw;
}
using namespace FastIo;
#define NUMBER1 500000
#define P(A) A=-~A
#define fione_i(begin,end) for(register int i=begin;i<=end;P(i))
#define tt(u) for(register int i=head[u];i;i=e[i].next)
#define ODT set<KDL>::iterator
using std::swap;
using std::set;
using std::iterator;
struct EDGE{int next,to;}e[(NUMBER1<<2)+5];
struct KDL{
	int l,r;
	mutable int v;
	KDL(int l,int r=0,int v=0):l(l),r(r),v(v){}
	bool operator<(const KDL &A)const{return l<A.l;}
};
set<KDL>odt;
int n,cnt(0),tot(0),top[NUMBER1+5],fa[NUMBER1+5],size[NUMBER1+5],son[NUMBER1+5],id[NUMBER1+5],depth[NUMBER1+5],head[NUMBER1+5];
inline void add(const int &u,const int &v){e[++tot].next=head[u];head[u]=tot,e[tot].to=v;}
void dfs1(int u,int fath,int deep){
	depth[u]=deep,fa[u]=fath,size[u]=1;
	int ms(-1);
	tt(u){
		if(e[i].to==fath)continue;
		dfs1(e[i].to,u,deep+1);
		size[u]+=size[e[i].to];
		if(size[e[i].to]>ms)ms=size[e[i].to],son[u]=e[i].to;
	}
}
void dfs2(int u,int tf){
	id[u]=++cnt,top[u]=tf;
	if(!son[u])return;
	dfs2(son[u],tf);
	tt(u){
		if(e[i].to==fa[u]||e[i].to==son[u])continue;
		dfs2(e[i].to,e[i].to);
	}
}
ODT split(int p){
	ODT it=odt.lower_bound(KDL(p));
	if(it!=odt.end()&&it->l==p)return it;
	--it;
	int l=it->l,r=it->r,v=it->v;
	odt.erase(it);
	odt.insert(KDL(l,p-1,v));
	return odt.insert(KDL(p,r,v)).first;
}
inline void assign(int l,int r,int v){
	ODT itr=split(r+1),itl=split(l);
	odt.erase(itl,itr);
	odt.insert(KDL(l,r,v));
}
inline int intervalsum(int p){
	ODT it=split(p);
	return it->v;
}
inline void treechange(int p){
	int tp=top[p];
	while(tp!=1){
		assign(id[tp],id[p],0);
		p=fa[tp],tp=top[p];
	}
	assign(id[1],id[p],0);
}
signed main(){
	int m,x,y;
	qrw.read(n);
	fione_i(2,n){
		qrw.read(x);
		qrw.read(y);
		add(x,y);add(y,x);
	}
	odt.insert(KDL(1,n,0));
	dfs1(1,0,1);
	dfs2(1,1);
	qrw.read(m);
	while(m--){
		qrw.read(y);
		qrw.read(x);
		if(y==1)assign(id[x],id[x]+size[x]-1,1);
		else if(y==2)treechange(x);
		else qrw.write(intervalsum(id[x]));	
	}
	fsh;
    exit(0);
    return 0;
}

标签:int,CodeForces343D,void,NUMBER1,Tree,Water,odt,qrw,id
From: https://www.cnblogs.com/SHOJYS/p/17416546.html

相关文章

  • el-tree实现自定义节点内容
    <!--*@Descripttion:el-tree实现自定义节点内容*@version:*@Author:zhangfan*@email:[email protected]*@Date:2020-07-0309:10:28*@LastEditors:zhangfan*@LastEditTime:2020-07-1611:21:20--><template><divclass="treeBo......
  • Uva--548 Tree(三个递归遍历/重建二叉树)
    记录23:132023-5-18uva.onlinejudge.org/external/5/548.htmlreference:《算法竞赛入门经典第二版》例题6-8使用中序遍历和后序遍历还原二叉树,还行,还是熟悉的。收获的点:使用数组快速建立二叉树(还是要变通,《数据结构与算法分析》中标准的使用了结构体指针,太过学术了?函数......
  • B. Fake Plastic Trees(贪心+dp)
    题目(FakePlasticTrees)[https://codeforces.com/problemset/problem/1693/B]题意输入T(≤1e3)表示T组数据。所有数据的n之和≤2e5。每组数据输入n(2≤n≤2e5)表示一棵n个节点的树,编号从1开始,1为根节点。然后输入p[2],p[3],...,p[n],其中p[i]表示i的父节......
  • 区块链实验-构建Merkle Tree
      主要内容:1.掌握MerkleTree的基本原理。2.编程实现MerkelTree的构建和数据完整性验证。实验条件:Win系统、Python实验内容:根据上图原理实现如下两个函数:#构建MerkleTreedefBuildTree(data):#验证数据完整性defValidate(hash,data):实现思......
  • Linux基础21 进程介绍, 进程监控状态ps, 进程相关命令pstree,pgrep,pidof, 动态进程监
    1.进程的管理:当我们运行一个程序,那么我们将该程序叫进程 进程线程协程 linux起服务会有给这个服务预分配的内存结构,windows没有 2.为什么要学进程管理?为了管理架构的服务 3.程序和进程的区别1)程序:开发写出来的代码,程序是永久存在的。 2)进程:它会随着程序的终止而销......
  • 1020 Tree Traversals
    题目:Supposethatallthekeysinabinarytreearedistinctpositiveintegers.Giventhepostorderandinordertraversalsequences,youaresupposedtooutputthelevelordertraversalsequenceofthecorrespondingbinarytree.InputSpecification:Eachi......
  • CF269D - Maximum Waterfall
    比较迷糊,比较乱搞。我们考虑从上往下进行\(dp\),\(dp_i\)表示从顶上水槽\(i\)最多的流量。然后我们发现,每个高度,能用来进行转移的区间一定没有被完全覆盖。也就是,只有在遮挡关系中被覆盖的区间可能被用来转移。同时,每个区间还是有要求的,比如\([1,3]\)的\([2,3]\)部分后来......
  • CF1777D Score of a Tree 题解
    题目简述给你一个\(n\)个结点根为\(1\)的树。在\(t=0\)时,每个结点都有一个值,为\(0\)或\(1\)。在每一个\(t>0\)时,每个结点的值都会变成其子结点在\(t-1\)时的值的异或和。定义\(S(t)\)为\(t\)时所有结点值的和。定义\(F(A)\)为树在\(0\let\le10^......
  • Java-Day-19( 对集合实现类的选择 + TreeSet + TreeMap )
    Java-Day-19总结-开发中如何选择集合实现类在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行选择先判断存储的类型(一组对象或一组键值对)一组对象(单列):Collection接口允许重复:List增删多:LinkedList[底层维护了一个双向链......
  • AtCoder Beginner Contest 207 F Tree Patrolling
    洛谷传送门AtCoder传送门简单树形dp。设\(f_{u,i,p=0/1,q=0/1}\)为\(u\)的子树中被覆盖点数为\(i\),\(u\)有没有被覆盖,\(u\)有没有被选。转移树形背包合并即可,需要分类讨论。要注意如果\(u\)没被覆盖,\(v\)选了,或者\(u\)选了,\(v\)没被覆盖,被覆盖点数要\(+1\)。......