[bzoj1103][POI2007]大都市meg_dfs序_树状数组

大都市meg bzoj-1103 POI-2007

题目大意:给定一颗n个点的树,m次操作。将一条路的边权更改成0;查询一个点到根节点的点权和。开始的时候所有边的边权都是1。

注释:$1\le n,m\le 2.5\cdot 10^5$。



想法:我们先拉出dfs序。其实严格来讲是出栈入栈序,就是每个点在序上出现两次的那个。

开始的时候入栈时的点权是1,出栈是-1。修改就是把出栈入栈都改成0。然后用树状数组查询前缀和即可。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 250010
using namespace std;
int tree[N<<1],val[N<<1],head[N],to[N<<1],nxt[N<<1],tot,cnt;
int dic[N<<1];
struct Node
{
	int x,y;
}a[N];
inline int lowbit(int x) {return x&(-x);}
void fix(int x,int delta)
{
	for(int i=x;i<=cnt+1;i+=lowbit(i))
	{
		// puts("fix");
		tree[i]+=delta;
	}
}
int query(int x)
{
	int ans=0;
	for(int i=x;i>=1;i-=lowbit(i))
	{
		// puts("query");
		ans+=tree[i];
	}
	return ans;
}
inline void add(int x,int y)
{
	to[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void dfs(int pos,int fa)
{
	// if(a[pos].x) puts("FUCK");
	dic[++cnt]=pos;
	// cnt++;
	val[cnt]=1;
	a[pos].x=cnt;
	for(int i=head[pos];i;i=nxt[i])
	{
		if(to[i]==fa) continue;
		dfs(to[i],pos);
	}
	dic[++cnt]=pos;
	// cnt++;
	val[cnt]=-1;
	a[pos].y=cnt;
}
int main()
{
	int n; cin >> n ;
	int x,y;
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y); add(y,x);
	}
	dfs(1,0);
	val[1]=0;
	val[cnt]=0;
	for(int i=1;i<=cnt;i++)
	{
		fix(i,val[i]);
	}
	// printf("Gun %d\n",cnt);
	// for(int i=1;i<=cnt;i++)
	// {
	// 	printf("Shit %d\n",dic[i]);
	// }
	// puts("--------------------------------------");
	int m; cin >> m ;
	char opt[10];
	// for(int i=1;i<=n;i++) printf("%d %d\n",a[i].x,a[i].y);
	for(int i=1;i<=n+m-1;i++)
	{
		// printf("Fuck %d\n",i);
		scanf("%s",opt+1);
		if(opt[1]==‘A‘)
		{
			scanf("%d%d",&x,&y);
			if(x>y) swap(x,y);
			fix(a[y].x,-1);
			fix(a[y].y,1);
		}
		else
		{
			scanf("%d",&x);
			// printf("%d\n",query(3));
			printf("%d\n",query(a[x].x));
		}
	}
	return 0;
}

小结:简单题。

原文地址:https://www.cnblogs.com/ShuraK/p/9551545.html

时间: 2024-10-20 02:39:46

[bzoj1103][POI2007]大都市meg_dfs序_树状数组的相关文章

【BZOJ1103】大都市meg(DFS序,树状数组)

题意:有一颗树,1号点为根,保证编号小的点深度较小,初始状态每条边都没有被标记,要求实现两个操作在线: A:将连接x,y的边标记 W:查询从1到x的路径上有多少条边未被标记 n<=2*10^5 思路:本题的特殊性质: 1.一次只标记一条边且没有重边 2.直接求1到x的路径,不用LCA 记录i点在DFS序中第一次与最后一次出现的时间b[i]与c[i] 可以发现若(x,y)(x<y)边被标记只对区间(b[y],c[y])有1的贡献 等价于前缀和s[b[y]]++ s[c[y]+1]-- 至于s[c

HDU 6203 ping ping ping(dfs序+LCA+树状数组)

http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意: n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连通.问无法通行的点最少有多少个. 思路: 贪心思维,破坏两个点的LCA是最佳的.那么怎么判断现在在(u,v)之间的路径上有没有被破坏的点呢,如果没有的话那么此时就要破坏这个lca点.一开始我们要把询问按照u和v的lca深度从大到小排序,如果某个点需要被破坏,那么它的所有子节点都可以不再需要破坏别的点

HDU 5156 - Harry and Christmas tree (dfs序+离线树状数组)

http://acm.hdu.edu.cn/showproblem.php?pid=5156 BC#25的C题. 题意是:给出一颗大小为n的树,以1为根,然后给出m次染色,每次将节点u加上一种颜色(一个节点可以有多个颜色). 最后查询树上每个节点对应子树上包含的不同颜色数量. 当时这场比赛没有做,回来看一下题目,没看标解就试着敲了一遍,于是解题思路从一开始就走上了不归路. 标解是O(n+m)的方法,主要思路是将问题转为:一次染色表示将u到根节点的路径都染上这种颜色. 但这样做需要去重,因为如果u

POJ 2763 Housewife Wind(DFS序+LCA+树状数组)

Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11419   Accepted: 3140 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beauti

BZOJ_3653_谈笑风生_树状数组

Description 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道 高明到哪里去了”. ? 设a 和 b 为 T 中的两个不同节点.如果 a 与 b 在树上的距离不超过某个给定 常数x,那么称“a 与b 谈笑风生”. 给定一棵n个节点的有根树T,节点的编号为1 到 n,根节点为1号节点.你需 要回答q 个询问,询问给定两个整数p和k,问有多少个有序三元组(a;b;c)满足: 1. a.b和 c为 T 中三个不同的点,且 a为

BZOJ_5055_膜法师_树状数组+离散化

Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘积, 但目前的宇宙很不乐观,胡乱偷取可能造成维度的崩溃, 所以,他必须按逆序偷取这些维度,且在偷取中, 每次偷取的维度的能量必须严格小于他上次偷取的能量, 由于膜法师生活在多元宇宙,所以他可以让所有可能的偷取方案全部发生 题目描述 但他数学不好,所以找到了你帮他求出能为长者续几秒, 你要做的,就是在

See you~_树状数组

Problem Description Now I am leaving hust acm. In the past two and half years, I learned so many knowledge about Algorithm and Programming, and I met so many good friends. I want to say sorry to Mr, Yin, I must leave now ~~>.<~~. I am very sorry, we

【bzoj1109】[POI2007]堆积木Klo 动态规划+树状数组

题目描述 Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体.每个积木上面都有一个数.Mary用他的所有积木垒了一个高塔.妈妈告诉Mary游戏的目的是建一个塔,使得最多的积木在正确的位置.一个上面写有数i的积木的正确位置是这个塔从下往上数第i个位置.Mary决定从现有的高塔中移走一些,使得有最多的积木在正确的位置.请你告诉Mary她应该移走哪些积木. 输入 第一行为一个数n,表示高塔的初始高度.第二行包含n个数a1,a2,...,an,表示从下到上每个积木上面的数. 输出 注意:请

[bzoj2131]免费的馅饼_树状数组

免费的馅饼 bzoj-2131 题目大意: 注释:$1\le n \le 10^5$,$1\le w \le 10^8$. 想法:首先,想到dp 状态:dp[i][j]表示i分钟在位置j的最大收益 优化优化 状态:dp[i]表示最后收到i的最大收益. 转移:顺序枚举i:1->n即可. 然后,我们尝试优化 对于这个状态我们会发现转移的时候有一个绝对值的死东西,我们将它拆开就有: 2*t[j]+pos[j]<=2*t[i]+pos[i]且2*t[j]-pos[j]<=2*t[i]-pos[i