原oj题面

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!的更多相关文章

  1. SPOJ VJudge QTREE - Query on a tree

    Query on a tree Time Limit: 851MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submi ...

  2. 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 ...

  3. SPOJ QTREE3 Query on a tree again! ——Link-Cut Tree

    [题目分析] QTREE2,一看是倍增算法,太懒了,不写了.( ̄_, ̄ ) QTREE3,树链剖分可以做,发现链上的问题LCT也很好做. 要是子树问题貌似可以DFS序. 然后就成LCT模板题了. 考前 ...

  4. 【SPOJ】375. Query on a tree(树链剖分)

    http://www.spoj.com/problems/QTREE/ 这是按边分类的. 调试调到吐,对拍都查不出来,后来改了下造数据的,拍出来了.囧啊啊啊啊啊啊 时间都花在调试上了,打hld只用了半 ...

  5. spoj 375 QTREE - Query on a tree 树链剖分

    题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...

  6. SPOJ 375 QTREE - Query on a tree

    思路 注意本题只能用C,不能用C++ 其他的都和上一题一样 代码 #include <stdio.h> #include <string.h> #define MAXN 100 ...

  7. 树链剖分【p4116】Qtree3 - Query on a tree

    Description 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑 ...

  8. Spoj 2798 Qtree3

    一棵结点为黑色或白色的树,初始都是白色的.有两种操作 1 将一个结点换颜色 2 询问从根到结点u路径上面的第一个黑色点,没有则输出-1 InputIn the first line there are ...

  9. SPOJ 16549 - QTREE6 - Query on a tree VI 「一种维护树上颜色连通块的操作」

    题意 有操作 $0$ $u$:询问有多少个节点 $v$ 满足路径 $u$ 到 $v$ 上所有节点(包括)都拥有相同的颜色$1$ $u$:翻转 $u$ 的颜色 题解 直接用一个 $LCT$ 去暴力删边连 ...

随机推荐

  1. vue封装一些常用组件loading、switch、progress

    vue封装一些常用组件loading.switch.progress github文档https://github.com/zengjielin/vue-component-library loadi ...

  2. centos7里创建用户和组

    1.创建组distro,其GID为2019groupadd -g 2019 distro 2.创建用户mandriva, 其ID号为1005:基本组为distro useradd mandriva - ...

  3. CentOS7 安装dotnet sdk 2.1.401 的简单办法

    1. 下载 linux版本的tar包 路径为: https://dotnet.microsoft.com/download/thank-you/dotnet-sdk-2.1.401-linux-x64 ...

  4. 在SSIS包中使用 Checkpoint从失败处重新启动包[转]

    使用SSIS做ETL的过程中会遇到各种各样的错误,对于一些大数据量的Job失败以后我们不希望重新运行,因为重新运行的时间开销是非常大的,我们只希望从失败的部分开始运行,这样可以省去很多的时间. SSI ...

  5. vue组件化编程应用

    写几个小案例来理解vue的组件化编程思想,下面是一个demo. 效果图示: 功能: Add组件用于添加用户评论,提交后右边评论回复会立马显示数据.Item组件点击删除可以删除当前用户评论.当List组 ...

  6. windows上安装 包管理工具choco及scoop

    1.安装 choco: 1.1.使用管理员方式打开 PowerShell 1.2.输入 Set-ExecutionPolicy RemoteSigned,输入 Y 1.3.安装 choco输入:iwr ...

  7. 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)

    洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...

  8. npm学习(一)之安装、更新以及管理npm版本

    安装npm 安装前须知: npm是在Node中编写的,因此需要安装Node.js才能使用npm.可以通过Node.js网站安装npm,或者安装节点版本管理器NVM. 如果只是想开始探索npm,使用No ...

  9. 1rem,1em,1vh,1px含义

    rem:相对于页面根元素<html>元素,通常做法是给html元素设置一个字体大小,然后其他元素的大小就是相对于根元素的大小 em:相对于父元素字体大小,元素的width/height/p ...

  10. 线性渐变css

    从上到下的线性渐变: #grad { background: -webkit-linear-gradient(red, blue); /* Safari 5.1 - 6.0 */ background ...