P3459 [POI2007]MEG-Megalopolis

题意

题目描述

Byteotia has been eventually touched by globalisation, and so has Byteasar the Postman, who once roamedthe country lanes amidst sleepy hamlets and who now dashes down the motorways. But it is those strolls inthe days of yore that he reminisces about with a touch of tenderness.

In the olden days nn Byteotian villages (numbered from 11 to nn) were connected by bidirectional dirt roadsin such a way, that one could reach the village number 11 (called Bitburg) from any other village in exactlyone way. This unique route passed only through villages with number less or equal to that of the startingvillage. Furthermore, each road connected exactly two distinct villages without passing through any othervillage. The roads did not intersect outside the villages, but tunnels and viaducts were not unheard of.

Time passing by, successive roads were being transformed into motorways. Byteasar remembers distinctly, when each of the country roads so disappeared. Nowadays, there is not a single country lane left in Byteotia - all of them have been replaced with motorways, which connect the villages into Byteotian Megalopolis.

Byteasar recalls his trips with post to those villages. Each time he was beginning his journey with letters to some distinct village in Bitburg. He asks you to calculate, for each such journey (which took place in a specific moment of time and led from Bitburg to a specified village), how many country roads it led through.

TaskWrite a programme which:

reads from the standard input:

descriptions of roads that once connected Byteotian villages, sequence of events: Byteasar's trips and the moments when respective roads were transformed into motorways, for each trip, calculates how many country roads Byteasar has had to walk, writes the outcome to the standard output.

在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员\(Blue \ Mary\)也开始骑着摩托车传递邮件了。不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为\(1 \cdots n\)的\(n\)个小村庄,某些村庄之间有一些双向的土路。从每个村庄都恰好有一条路径到达村庄\(1\)(即比特堡)。并且,对于每个村庄,它到比特堡的路径恰好只经过编号比它的编号小的村庄。另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。在这个未开化的地方,从来没有过高架桥和地下铁道。随着时间的推移,越来越多的土路被改造成了公路。至今,\(Blue \ Mary\)还清晰地记得最后一条土路被改造为公路的情景。现在,这里已经没有土路了——所有的路都成为了公路,而昔日的村庄已经变成了一个大都市。\(Blue \ Mary\)想起了在改造期间她送信的经历。她从比特堡出发,需要去某个村庄,并且在两次送信经历的间隔期间,有某些土路被改造成了公路。现在\(Blue \ Mary\)需要你的帮助:计算出每次送信她需要走过的土路数目。(对于公路,她可以骑摩托车;而对于土路,她就只好推车了。)

输入输出格式

输入格式:

In the first line of the standard input there is a single integer \(n\) (\(1 \leq n \leq 250 \ 000\)),denoting the number of villages in Byteotia. The following \(n-1\) lines contain descriptions of the roads, in the form of two integers \(a,b\) (\(1 \leq a<b \leq n\))separated by a single space, denoting the numbers of villages connected with a road. Inthe next line there is a single integer \(m\)(\(1 \leq m \leq 250 \ 000\)),denoting the number of trips Byteasar has made.

The following \(n+m-1\) lines contain descriptions of the events, in chronological order:

A description of the form "A \(a\) \(b\)"(for \(a<b\)) denotes a country road between villages \(a\) and \(b\) beingtransformed into a motorway in that particular moment.

A description of the from "W \(a\)" denotes Byteasar's trip from Bitburg to village \(a\).

输出格式:

Your programme should write out exactly \(m\) integers to the standard output, one a line, denoting the numberof country roads Byteasar has travelled during his successive trips.

输入输出样例

输入样例:

5
1 2
1 3
1 4
4 5
4
W 5
A 1 4
W 5
A 4 5
W 5
W 2
A 1 2
A 1 3

输出样例:

2
1
0
1

思路

数据过水。 --logeadd

简单地说,给你一棵树,树上的边权都是\(1\),接下来有两种操作,一种把一条边的边权改为\(0\),另一种询问某个结点到根节点\(1\)的边权之和。这不就是一道树剖板子题吗?于是这样想的我在考场上被卡掉了一个点(不过听\(logeadd\)巨佬说洛谷上交树剖也能过)。

树剖的时间复杂度为\(O(n \log ^2n)\),显然会挂,能不能优化到\(O(n \log n)\)呢?对于每次修改操作,被修改边所指向的子树中的所有结点的答案都会减少一,我们不如在线段树中直接记录答案,每次只进行一次区间修改,也就是修改子树,询问时单点询问,这样时间复杂度就可以变为\(O(n \log n)\)了。

从另一个角度来想,我们处理出树的\(dfs\)序,然后要用一种支持区间修改和单点查询的时间复杂度都不大于\(O(\log n)\)的数据结构,同样,我们也可以大力一发树状数组过了这道题。这里提供的是线段树做法。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=250005;
int n,m,tot,sz[MAXN],dfn[MAXN],dep[MAXN],a[MAXN];
int cnt,top[MAXN],to[MAXN<<1],nex[MAXN<<1];
struct SegmentTree
{
int l,r,data,tag;
#define l(a) tree[a].l
#define r(a) tree[a].r
#define d(a) tree[a].data
#define t(a) tree[a].tag
}tree[MAXN<<2];
int read()
{
int re=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();
return re;
}
char readc()
{
char ch=getchar();
while(!isalpha(ch)) ch=getchar();
return ch;
}
void dfs(int now)
{
dfn[now]=++tot,a[tot]=dep[now],sz[now]=1;
for(int i=top[now];i;i=nex[i])
{
if(dfn[to[i]]) continue;
dep[to[i]]=dep[now]+1;
dfs(to[i]);
sz[now]+=sz[to[i]];
}
}
void build(int p,int ll,int rr)
{
l(p)=ll,r(p)=rr;
if(ll==rr)
{
d(p)=a[ll];
return ;
}
int mid=(ll+rr)>>1;
build(p<<1,ll,mid);
build(p<<1|1,mid+1,rr);
d(p)=d(p<<1)+d(p<<1|1);
}
void pushdown(int p)
{
if(t(p))
{
d(p<<1)-=t(p)*(r(p<<1)-l(p<<1)+1),d(p<<1|1)-=t(p)*(r(p<<1|1)-l(p<<1|1)+1);
t(p<<1)+=t(p),t(p<<1|1)+=t(p);
t(p)=0;
}
}
void change(int p,int ll,int rr)
{
if(ll<=l(p)&&r(p)<=rr)
{
d(p)-=r(p)-l(p)+1;
t(p)++;
return ;
}
pushdown(p);
int mid=(l(p)+r(p))>>1;
if(ll<=mid) change(p<<1,ll,rr);
if(rr>mid) change(p<<1|1,ll,rr);
d(p)=d(p<<1)+d(p<<1|1);
}
int ask(int p,int des)
{
if(l(p)==r(p)) return d(p);
pushdown(p);
int mid=(l(p)+r(p))>>1;
if(des<=mid) return ask(p<<1,des);
else return ask(p<<1|1,des);
}
int main()
{
n=read();
for(int i=0;i<n-1;i++)
{
int x=read(),y=read();
to[++cnt]=y,nex[cnt]=top[x],top[x]=cnt;
to[++cnt]=x,nex[cnt]=top[y],top[y]=cnt;
}
dfs(1);
build(1,1,n);
m=read()+n-1;
while(m--)
{
char opt=readc();
if(opt=='A')
{
int x=read(),y=read();
if(dfn[x]<dfn[y]) swap(x,y);
change(1,dfn[x],dfn[x]+sz[x]-1);
}
else if(opt=='W') printf("%d\n",ask(1,dfn[read()]));
}
return 0;
}

Luogu P3459 [POI2007]MEG-Megalopolis(线段树)的更多相关文章

  1. luogu P2574 XOR的艺术 (线段树)

    luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\( ...

  2. 【原创】洛谷 LUOGU P3373 【模板】线段树2

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第 ...

  3. 【原创】洛谷 LUOGU P3372 【模板】线段树1

    P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...

  4. Luogu P1198 BZOJ 1012 最大数 (线段树)

    手动博客搬家: 本文发表于20170821 14:32:05, 原地址https://blog.csdn.net/suncongbo/article/details/77449455 URL: (Lu ...

  5. 【Luogu P3834】可持久化线段树(主席树)

    Luogu P3834 可持久化数据结构就是支持在历史版本上进行查询和修改操作的数据结构. 主席树就是对线段树的改进,使之可持久化. 前置知识:动态开点线段树 我们利用权值(值域)线段树统计区间内的数 ...

  6. 「Luogu P5494 【模板】线段树分裂」

    (因为没有认证,所以这道题就由Froggy上传) 线段树分裂用到的地方确实并不多,luogu上以前也没有这道模板题,所以就出了一道,实在是想不出怎么出模板了,所以这道题可能可以用一些其他的算法水过去. ...

  7. [Luogu P2824] [HEOI2016/TJOI2016]排序 (线段树+二分答案)

    题面 传送门:https://www.luogu.org/problemnew/show/P2824 Solution 这题极其巧妙. 首先,如果直接做m次排序,显然会T得起飞. 注意一点:我们只需要 ...

  8. luogu P3373 【模板】线段树 2

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别 ...

  9. Luogu P4097 [HEOI2013]Segment 李超线段树

    题目链接 \(Click\) \(Here\) 李超线段树的模板.但是因为我实在太\(Naive\)了,想象不到实现方法. 看代码就能懂的东西,放在这里用于复习. #include <bits/ ...

随机推荐

  1. 19.SimLogin_case02

    # 模拟登录马蜂窝 import requests from lxml import etree session = requests.Session() phone_number = input(' ...

  2. Java之RabbitMQ(二)多mq配置

    场景: springboot单项目,自身使用mq中间件处理一些业务需求,某些业务上又需要消费第三方mq消息,这时候需要我们单项目中配置多套mq,这时候,需要我们自定义多套mq相关连接工厂.模板.监听工 ...

  3. 爬虫所需要的文档和自动化文本driver下载地址,以及制作词云的文档,api等

    Scrapy1.7.3文档 webdriver文档 webdriver下载地址 Chrom各版本下载地址 词云1.5文档 selenium中文文档 vue数据可视化文档 element开发组件 其他好 ...

  4. 数据库DQL、DML、DDL及DCL详解

    目录 1. 数据查询语言(DQL,Data Query Language) 2. 数据操纵语言(DML,Data Manipulation Language) 3. 数据定义语言(DDL,Data D ...

  5. Vim操作 -- 多段复位粘贴

    Vim可以多段复制.粘贴.即,内容X复制到寄存器“1”,内容Y复制到寄存器“2”:粘贴时可以选择从“1”还是“2”粘贴. (1) Vim有13个粘贴板,分别是0.1.2.....9.a.“.+:用:r ...

  6. ConcurrentHashMap 和 Hashtable 的区别

    ConcurrentHashMap 和 Hashtable 的区别主要体现在实现线程安全的方式上不同. 1.底层的数据结构: ConcurrentHashMap 在jdk1.7之前采用的是 分段的数组 ...

  7. 解决CentOS“Zabbix discoverer processes 75% busy”的问题

    解决CentOS“Zabbix discoverer processes 75% busy”的问题 运维  立杰  4年前 (2014-08-11)  1104℃  0评论 在使用Zabbix过程中, ...

  8. Windows进程创建的流程分析

    .   创建进程的大体流程:   创建进程的过程就是构建一个环境,这个环境包含了很多的机制 (比如自我保护, 与外界通信等等). 构建这个环境需要两种"人"来协调完成(用户态和内核 ...

  9. 解决编译GCC内存不足的错误

    近期在使用阿里和腾讯的云服务器,由于只是测试用所以只租用了廉价512的内存,在编译gcc时遇到错误,表面上看只是编译错误,并且原因不明,纠结了几次之后猜测应该是由于系统资源不足导致的,所以尝试增加系统 ...

  10. 一个四五年的Java开发程序员,该准备哪些去面试?

    上周面试了一周,感触颇深,总结一下. 面试了公司大概有阿里,携程,爱奇艺,唯品会,途牛,bilibili,大众点评,阿里和爱奇艺是电话面试,其他现场面试. 首先,五年左右,应该算高级开发工程师,大部分 ...