SPOJ 2798 QTREE3 - Query on a tree again!
Time limit 2000 ms
Memory limit 1572864 kB
Code length Limit 50000 B
OS Linux
Language limit All except: ERL JS-RHINO NODEJS PERL6 VB.NET //c++呢?Java呢?Python呢?明明可以的
Source VNOI Marathon '08 - Round 6/DivA Problem Setter: Blue Mary
Author Fudan University Problem Setters
吐槽
两年后写的第二篇树剖,还是找了一两天的bug,最后发现,dfs1()
里,if(v==t[u].fa) continue;
被我写成了if(v==t[u].fa) return;
。这样例里的树好像也不水了……而且我记得之前把建好的树输出,也没发现树上少了哪个点来着……不知道这个错误发生之前是不是有其他什么bug……
[HAOI2015]树上操作 这篇的操作3也是从根节点到给定点这一路的修改,我当年还觉得那时自己想的优化(因为一个点已经固定为根节点1,所以跳链时不用比较两条链顶端的深度,只需要下面那个点不停向上到达根就好)挺不错来着,结果现在发现只是那常规操作……
板子没有解题思路
源代码
#include<cstdio>
#include<cstring>
#include<algorithm>
int T;
int n,q;
//对于每个黑色点,线段树上的值对应点的新id
//对于每个白色点,线段树上的值为inf
struct Edge{
int nxt,to;
}e[200010];
int cnt=1,head[100010];
void add(int u,int v)
{
e[cnt]={head[u],v};
head[u]=cnt++;
e[cnt]={head[v],u};
head[v]=cnt++;
}
struct Tree{
int fa,dep,sz,wson;
int id,top;
}t[100010];
void dfs1(int u,int fa)
{
t[u].fa=fa;
t[u].dep=t[fa].dep+1;
t[u].sz=1;
int maxn=-1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa) continue;//就是这里,之前写成return了
dfs1(v,u);
int temp=t[v].sz;
t[u].sz+=temp;
if(temp>maxn)
{
maxn=temp;
t[u].wson=v;
}
}
}
int id=1;
int mp[100010];//用新的id查询老的id
void dfs2(int u,int top)
{
t[u].top=top;
mp[id]=u;
t[u].id=id++;
if(t[u].sz==1) return;
dfs2(t[u].wson,top);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==t[u].wson||v==t[u].fa) continue;
dfs2(v,v);
}
}
const int inf=0x7f7f7f7f;
struct Segtree{
int l,r;//有点想改变码风,把这两个放到参数里去,以便和主席树统一
int mn;
}s[400010];
void build(int x,int l,int r)
{
s[x]={l,r,inf};
if(l==r) return;
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
}
void update(int x,int pos)
{
if(s[x].l==s[x].r&&s[x].l==pos)
{
if(s[x].mn==inf)//染成黑色
s[x].mn=pos;//赋值成新的id
else//染成白色
s[x].mn=inf;
return;
}
int mid=s[x].l+s[x].r>>1;
if(pos<=mid) update(x<<1,pos);
else update(x<<1|1,pos);
s[x].mn=std::min(s[x<<1].mn,s[x<<1|1].mn);
}
int que(int x,int l,int r)//返回所求点新id
{
if(l<=s[x].l&&s[x].r<=r)
return s[x].mn;
int mid=s[x].l+s[x].r>>1;
int ans=inf;
if(l<=mid) ans=std::min(ans,que(x<<1,l,r));
if(r>mid) ans=std::min(ans,que(x<<1|1,l,r));
return ans;
}
void opt0(int u)//改变u号点颜色
{
update(1,t[u].id);
}
int opt1(int u)//返回1到u的第一个黑点的老id
{
int ans=inf;
while(u)
{
ans=std::min(ans,que(1,t[t[u].top].id,t[u].id));
u=t[t[u].top].fa;
}
if(ans==inf) ans=-1;
else ans=mp[ans];
return ans;
}
int main()
{
//freopen("test.in","r",stdin);
scanf("%d%d",&n,&q);
for(int i=1,u,v;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
while(q--)
{
int opt,u;
scanf("%d%d",&opt,&u);
if(opt) printf("%d\n",opt1(u));
else opt0(u);
}
return 0;
}
SPOJ 2798 QTREE3 - Query on a tree again!的更多相关文章
- SPOJ VJudge QTREE - Query on a tree
Query on a tree Time Limit: 851MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submi ...
- SPOJ QTREE3 - Query on a tree again!
You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are number ...
- SPOJ QTREE3 Query on a tree again! ——Link-Cut Tree
[题目分析] QTREE2,一看是倍增算法,太懒了,不写了.( ̄_, ̄ ) QTREE3,树链剖分可以做,发现链上的问题LCT也很好做. 要是子树问题貌似可以DFS序. 然后就成LCT模板题了. 考前 ...
- 【SPOJ】375. Query on a tree(树链剖分)
http://www.spoj.com/problems/QTREE/ 这是按边分类的. 调试调到吐,对拍都查不出来,后来改了下造数据的,拍出来了.囧啊啊啊啊啊啊 时间都花在调试上了,打hld只用了半 ...
- spoj 375 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- SPOJ 375 QTREE - Query on a tree
思路 注意本题只能用C,不能用C++ 其他的都和上一题一样 代码 #include <stdio.h> #include <string.h> #define MAXN 100 ...
- 树链剖分【p4116】Qtree3 - Query on a tree
Description 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑 ...
- Spoj 2798 Qtree3
一棵结点为黑色或白色的树,初始都是白色的.有两种操作 1 将一个结点换颜色 2 询问从根到结点u路径上面的第一个黑色点,没有则输出-1 InputIn the first line there are ...
- SPOJ 16549 - QTREE6 - Query on a tree VI 「一种维护树上颜色连通块的操作」
题意 有操作 $0$ $u$:询问有多少个节点 $v$ 满足路径 $u$ 到 $v$ 上所有节点(包括)都拥有相同的颜色$1$ $u$:翻转 $u$ 的颜色 题解 直接用一个 $LCT$ 去暴力删边连 ...
随机推荐
- 关于Goroutine与Channel
关于Goroutine的原理 原理上的内容比较多,比如goroutine启动的时候要执行哪些相关的操作,一点一点的补充一下. channel的基本原理 channel是go语言中的特殊的机制,既可以同 ...
- 本地项目代码上传至github
初始化本地目录:git init cd到个人本地项目代码文件目录下,执行git init命令 添加项目文件到本地仓库:git add . git commit -m "提交说明" ...
- win10远程桌面报出现身份验证错误,要求的函数不受支持
win10远程桌面报出现身份验证错误,要求的函数不受支持 编写人:左丘文 2019-6-6 公司换了一台新笔记本电脑,是win10操作系统,刚想远程连接一下服务器,发现以前很正常的功能,发现不行了.网 ...
- Codeforces 1262F Wrong Answer on test 233(组合数)
E1:设dp[i][j],表示在第i个位置的当前新状态超过原状态j分的方案数是dp[i][j],那么对于这种情况直接进行转移即可,如果a[i]==b[i]显然k种选择都可以,不影响j,如果不一样,这个 ...
- MyBatis一个对多个主键(索引)生成实体类的处理
原数据库表: 生成实体类,多出了一个xxKey.java
- spring boot配置分页插件
在springboot中使用PageHelper插件有两种较为相似的方式,接下来我就将这两种方式进行总结. 方式一:使用原生的PageHelper 1.在pom.xml中引入依赖 <depend ...
- Java创建二叉树
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/yeweiouyang/article/details/37814461 二叉树的值保存在数组中,以0 ...
- logstash启动时找不到自定义的JAVA_HOME环境变量
logstash java 版本问题 配置logstash收集应用日志时出现报错,说是找不到JAVA_HOME环境变量,但是明明已经设置了 logstash要求java 1.8以上,查看生产环境: [ ...
- Could not locate executable null\bin\winutils.exe in the Hadoop binaries解决方式
1. 问题: 2. 问题解决: 仔细查看报错是缺少winutils.exe程序. Hadoop都是运行在Linux系统下的,在windows下eclipse中运行mapreduce程序,要首先安装 ...
- 使用英特尔® 驱动程序和支持助理更新英特尔®固态盘数据中心工具(英特尔®固态盘 DCT)后仍旧提示更新
再regedit中搜索原始版本,位于计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{82F015 ...