[CodeForces620E] New Year Tree

原题网址:http://codeforces.com/problemset/problem/620/E

啊,从这篇博客开始我就不复制题目了,毕竟大家点进来都是为了我的AC代码。

好的,这道题的题目大意就是,有一棵树,给它染色,刚开始的颜色是给定的,然后有两个操作:

1,输入v,x,将v和其所有子节点染色成x;

2,输入x,输出x的所有子节点的染色种类;

很显然,这个输入和输出的方式很有区间的味道(行家啊~

于是,我们考虑到dfs序,可以把一棵树降维到一维;

然后,我就写了一个朴素的欧拉序(节点进出的时候记录进dfs_num数组)

然后,,,我要怎么数颜色???

瞄了一眼数据范围,最多60种颜色,这明白着提醒我:放心吧,随便开数组,不会mle的~

//在教练的提醒下我选择了状压

把每种颜色作为二进制下的一位,比如(1000)2就表示这个节点有3号颜色;

区间合并的时候,就按位或一下,比如表示颜色三的(1000)和表示颜色二的(100)按位或后就是(1100)表示既有三又有二;

如果有多种颜色的时候,这种方法可以起到有效的去重(这让本打算开60个数组的我情何以堪

于是代码就出来了

漂亮得TLE了。。。

 

然后优化就是把欧拉序改成了前序遍历,就AC了

下面放AC代码

#include
#include
#include
#include
#define maxn 400005
using namespace std;
inline void read(int &x)
{
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*f;
}
inline void read(long long &x)
{
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*f;
}
int N,M;
long long color_v[maxn];
long long bas=1;
struct node{
	int nex,to;
}edge[maxn<<2];
int head[maxn],tot;
inline void insert(int from,int to)
{
	tot++;
	edge[tot].nex=head[from];
	head[from]=tot;
	edge[tot].to=to;
}
long long st[maxn],ed[maxn],dfs_num[maxn],t;
void dfs(int x,int u)
{
	//cout<<"dfs note: "<>=1;
	}
	return ans;
}
void push_up(int rt)
{
	tree[rt].color=tree[rt<<1].color|tree[rt<<1|1].color;
}
void push_down(int rt)
{
	tree[rt<<1].color=tree[rt].color;
	tree[rt<<1|1].color=tree[rt].color;
}
void build(int rt,int l,int r)
{
	tree[rt].l=l;
	tree[rt].r=r;
	if(l==r)
	{
		tree[rt].color=bas<>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	push_up(rt);
}
void update(int rt,int l,int r,int col)
{
	if(tree[rt].l>r||tree[rt].r=l&&tree[rt].r<=r)
	{
		tree[rt].color=bas<>1;
	if(l<=mid)
		update(rt<<1,l,r,col);
	if(r>mid)
		update(rt<<1|1,l,r,col);
	push_up(rt);
}
long long query(int rt,int l,int r)
{
	if(tree[rt].l>r||tree[rt].r=l&&tree[rt].r<=r)
	{
		return tree[rt].color;
	}	
	if(tree[rt].l==tree[rt].r)
		return 0;
	if(bit(tree[rt].color)==1)
		push_down(rt);
	int mid=tree[rt].l+tree[rt].r>>1;
	long long ans=0;
	if(l<=mid)
	{
		ans|=query(rt<<1,l,r);
	}
	/*if(ans==(1<<23))
		cout<<"LEFT ERROR:  "<mid)
	{
		ans|=query(rt<<1|1,l,r);
	}	
	return ans;
}
/*void search(long long rt)
{
	if(bit(tree[rt].color)==1)
	{
		for(long long i=tree[rt].l;i<=tree[rt].r;i++)
			cout<

 

你可能感兴趣的:(解题报告)