http://www.spoj.com/problems/QTREE3/

时间限制:2s    代码长度限制:50000B     内存限制:1536MB

【题目描述】

给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白

有两种操作:

0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑)

1 v : 询问1到v的路径上的第一个黑点,若无,输出-1

总共有12组数据。

1/3 的数据, N=5000, Q=400000.

1/3 的数据, N=10000, Q=300000.

1/3 的数据,N=100000, Q=100000.

【输入格式】

单组数据的。

第一行 N and Q.表示N个点和Q个操作

下来N-1条无向边

下来 Q行,每行一个操作"0 i" 或者"1 v" (1 ≤ i, v ≤ N).

【输出格式】

遇到 "1 v"操作的时候,输出结果。

这题就是树链剖分,线段树维护当前区间最左边的黑点的编号因为是单点修改,所以根本不用lazy,也不用记录点的颜色(看它所维护的最左边的点这个值是否为0)。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; const int N=;
struct trnode{
int lc,rc,l,r,c,d,lazy;
}t[*N];
struct node{
int x,y,next;
}a[*N];
int n,m,tl,z,len;
int first[N],tot[N],son[N],fa[N],dep[N],ys[N],yss[N],top[N]; void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=first[x];first[x]=len;
} int maxx(int x,int y){return x>y ? x:y;}
int minn(int x,int y){return x<y ? x:y;} int build_tree(int l,int r)
{
int x=++tl;
t[x].l=l;t[x].r=r;
t[x].c=t[x].d=t[x].lazy=;
t[x].lc=t[x].rc=;
if(l<r)
{
int mid=(l+r)>>;
t[x].lc=build_tree(l,mid);
t[x].rc=build_tree(mid+,r);
}
return x;
} void change(int x,int p)
{
int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)>>;
if(t[x].l==t[x].r)
{
if(t[x].d==) t[x].d=t[x].l;
else t[x].d=;
return;
}
if(p<=mid) change(lc,p);
else change(rc,p);
if(t[lc].d) t[x].d=t[lc].d;
else if(t[rc].d) t[x].d=t[rc].d;
else t[x].d=;
} int query(int x,int l,int r)
{
if(t[x].l==l && t[x].r==r) return t[x].d;
int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)>>;
if(r<=mid) return query(lc,l,r);
else if(l>mid) return query(rc,l,r);
else
{
int t1=query(lc,l,mid);
if(t1) return t1;
int t2=query(rc,mid+,r);
if(t2) return t2;
return ;
}
} void dfs1(int x)
{
tot[x]=;son[x]=;
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y==fa[x]) continue;
fa[y]=x;
dep[y]=dep[x]+;
dfs1(y);
if(tot[son[x]]<tot[y]) son[x]=y;
tot[x]+=tot[y];
}
} void dfs2(int x,int tp)
{
ys[x]=++z;yss[z]=x;top[x]=tp;
if(son[x]) dfs2(son[x],tp);
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y==fa[x] || y==son[x]) continue;
dfs2(y,y);
}
} int solve(int y)
{
int ty=top[y],ans=-;
while(ty!=)
{
int t=query(,ys[ty],ys[y]);
if(t) ans=yss[t];
y=fa[ty];ty=top[y];
}
int t;
if(y==) t=query(,,);
else t=query(,,ys[y]);
if(t) ans=yss[t];
return ans;
} int main()
{
freopen("a.in","r",stdin);
// freopen("me.out","w",stdout);
scanf("%d%d",&n,&m);
tl=;len=;z=;
memset(first,,sizeof(first));
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y),ins(y,x);
}
build_tree(,n);
fa[]=;dep[]=;dfs1();
dfs2(,);
for(int i=;i<=m;i++)
{
int tmp,x;
scanf("%d%d",&tmp,&x);
if(!tmp) change(,ys[x]);
else
{
int ans=solve(x);
if(ans) printf("%d\n",ans);
else printf("-1\n");
}
}
return ;
}

【SPOJ-QTREE3】树链剖分的更多相关文章

  1. SPOJ 375 树链剖分

    SPOJ太慢了,SPOJ太慢了, 题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权:2.查询u,v之间路径上的最大边权. 分析:树链剖分入门题,看这里: ...

  2. SPOJ QTREE 树链剖分

    树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...

  3. SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I 给你一棵有边权的树,有两个操作:一个操作是输出l到 ...

  4. SPOJ 375 (树链剖分+线段树)

    题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...

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

    人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...

  6. Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  7. spoj 375 树链剖分模板

    /* 只是一道树链刨分的入门题,作为模板用. */ #include<stdio.h> #include<string.h> #include<iostream> ...

  8. 【学术篇】SPOJ QTREE 树链剖分

    发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...

  9. spoj 375 树链剖分 模板

    QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...

  10. Qtree3 - 树链剖分

    打完以后才发现写复杂了……算了懒得改了 #include <bits/stdc++.h> using namespace std; ],fa[][],size[],wson[],vis[] ...

随机推荐

  1. VINS紧耦合优化公式及代码解析

    1.首先确定待优化的状态变量 对应代码,优化参数为: Vector3d Ps[(WINDOW_SIZE + )];(平移向量) Vector3d Vs[(WINDOW_SIZE + )];(速度) M ...

  2. 活动的生命周期 Android

    1.运行程序 onCreate().onStart()和 onResume() 2.跳转到非弹框视图控制器 onPause()和 onStop() 返回上一个视图控制器(没被回收) onRestart ...

  3. 自动化测试--封装getDriver的方法

    在自动化测试的时候,通常都会把最常用的功能封装起来,实现通用性. 该篇博客是实现了getDriver方法的封装. 第一次封装的时候,是使用的传参. @Parameters(value = {" ...

  4. Jmeter和Charles下载文件

    有时候我们jmeter做自动化测试是会遇到文件上传和文件下载的接口,这里我将接结合Charles来Jmeter 文件下载进行讲解 一.用Charles抓包分析文件下载接口 1.1.业务中文件下载链接如 ...

  5. 深入Python的类和对象

    多态:不同的子类对象,可以调用相同的父类方法,通过改写父类的方法,产生不同的执行结果 instance和type的区别: instance能够顺延到父类,比对对象与父类是否类型一致.而type只能比对 ...

  6. Laxcus大数据管理系统2.0(3)- 第一章 基础概述 1.2 产品特点

    1.2 产品特点 Laxcus大数据管理系统运行在计算机集群上,特别强调软件对分布资源可随机增减的适应性.这种运行过程中数据动态波动和需要瞬时感知的特点,完全不同与传统的集中处理模式.这个特性衍生出一 ...

  7. 小心!FOMO3D的坑

    null 01 前方高能 近日,区块链机构安比(SECBIT)实验室审计后确认,FOMO3D游戏的智能合约存在随机数漏洞可被利用,FOMO3D合约及所有抄袭源码的山寨合约均存在该安全漏洞. 原本设计上 ...

  8. MySQL初始4--去重

    更新表中的字段: update 表名 set 字段=新值,… where 条件: UPDATE语法可以用新值更新原有表行中的各列.SET子句指示要修改哪些列和要给予哪些值.WHERE子句指定应更新哪些 ...

  9. 【iOS开发】字典的快速赋值 setValuesForKeysWithDictionary

    前言 在学习解析数据的时候,我们经常是这么写的:PersonModel.h文件中 @property (nonatomic,copy)NSString *name; @property (nonato ...

  10. 软工实践 - 第二十四次作业 Beta 冲刺(2/7)

    队名:起床一起肝活队 组长博客:https://www.cnblogs.com/dawnduck/p/10105380.html 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过 ...