hdu5893 List wants to travel
裸的树链剖分加线段树区间修改
区间合并时需要多注意一点
当时写的很慢 理解不深刻
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 40005;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int N,M;
struct Pode{
int to,next;
}edge[MAXN * 2];
int tot;
int head[MAXN];
int E[MAXN][3];
void addedge(int x,int y){
edge[tot].to = y; edge[tot].next = head[x]; head[x] = tot ++;
}
int top[MAXN],fa[MAXN],son[MAXN],deep[MAXN],num[MAXN],p[MAXN],fp[MAXN],pos;
void dfs1(int x,int pre,int dep){
deep[x] = dep;
fa[x] = pre;
num[x] = 1;
for(int i = head[x]; i != -1; i = edge[i].next){
int y = edge[i].to;
if(y == pre) continue;
dfs1(y,x,dep + 1);
num[x] += num[y];
if(son[x] == -1 || num[y] > num[son[x]])
son[x] = y;
}
}
void dfs2(int x,int tp){
top[x] = tp;
p[x] = pos++;
fp[p[x]] = x;
if(son[x] == -1) return;
dfs2(son[x],tp);
for(int i = head[x] ; i != -1; i = edge[i].next){
int y = edge[i].to;
if(y != son[x] && y != fa[x])
dfs2(y,y);
}
}
int ininum[MAXN];
struct Node{
int l,r, num;
Node(int a=-1, int b=0, int c=0):l(a), r(b), num(c){}
Node operator + (const Node &T)const {
if(l == -1) return T; if(T.l == -1) return Node(l,r,num);
Node tt;
tt.l = l; tt.r = T.r;
tt.num = num+T.num;
if(r == T.l) tt.num--;
return tt;
}
Node rev(){
return Node(r,l,num);
}
};
struct Segtree{
Node tree[MAXN<<2];
int lazy[MAXN<<2];
void Pushup(int rt){
tree[rt] = tree[rt<<1]+tree[rt<<1|1];
}
void Pushdown(int rt) {
if(lazy[rt] != -1) {
lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
tree[rt<<1|1] = tree[rt<<1] = Node(lazy[rt], lazy[rt], 1);
lazy[rt] = -1;
}
}
void Build(int l,int r,int rt) {
lazy[rt] = -1;
if(l == r) {
tree[rt] = Node(ininum[l], ininum[l], 1);
return;
}
int m = (l+r) >>1;
Build(lson); Build(rson);
Pushup(rt);
}
void Change(int L,int R,int num,int l,int r,int rt) {
if(L <= l && r <= R) {
tree[rt] = Node(num,num,1);
lazy[rt] = num;
return;
}
int m = (l+r) >>1;
Pushdown(rt);
if(L <= m) Change(L,R,num,lson);
if(R > m) Change(L,R,num,rson);
Pushup(rt);
}
Node Sum(int L,int R,int l,int r,int rt){
if(L <= l && r <= R) {
return tree[rt];
}
int m = (l + r) >> 1;
Node ans;
Pushdown(rt);
if(L <= m) ans = ans+Sum(L,R,lson);
if(R > m) ans = ans+Sum(L,R,rson);
return ans;
}
void Find(int x,int y,int d){
int t1 = top[x]; int t2 = top[y];
while(t1 != t2) {
if(deep[t1] < deep[t2]) {
swap(t1,t2); swap(x,y);
}
Change(p[t1], p[x], d, 1,N,1);
x = fa[t1];
t1 = top[x];
}
if(x == y) return;
if(deep[x] > deep[y]) {
swap(x,y);
}
Change(p[son[x]], p[y], d,1, N, 1);
}
Node Query(int x,int y){
int t1 = top[x]; int t2 = top[y];
Node X, Y;
while(t1 != t2) {
if(deep[t1] < deep[t2]){
Y = Sum(p[t2], p[y], 1,N,1)+Y;
y = fa[t2]; t2 = top[y];
}else {
X = Sum(p[t1], p[x], 1,N,1)+X;
x = fa[t1]; t1 = top[x];
}
}
if(x == y) return X+Y;
if(deep[x] > deep[y]){
return Y.rev() + Sum(p[son[y]], p[x], 1,N,1) + X;
}else {
return X.rev() + Sum(p[son[x]], p[y], 1,N,1) + Y;
}
}
}solve;
int main(){
while(~scanf("%d %d",&N,&M)){
memset(head,-1,sizeof(head));
memset(son, -1, sizeof(son));
tot = 0;
pos = 1;
for(int i = 1; i < N; ++i){
scanf("%d%d%d",&E[i][0],&E[i][1],&E[i][2]);
addedge(E[i][0], E[i][1]); addedge(E[i][1], E[i][0]);
}
dfs1(1,0,1);
dfs2(1,1);
ininum[0] = 0;
for(int i = 1; i < N; ++i){
if(deep[E[i][0]] < deep[E[i][1]]) swap(E[i][0], E[i][1]);
ininum[ p[E[i][0]] ] = E[i][2];
}
solve.Build(1,N,1);
for(int i = 1; i <= M; ++i) {
char a[10]; int b,c,d;
scanf("%s",a);
if(a[0] == 'C') {
scanf("%d %d %d",&b,&c,&d);
solve.Find(b,c,d);
}else {
scanf("%d %d",&b,&c);
printf("%d\n", solve.Query(b,c).num );
}
}
}
return 0;
}
hdu5893 List wants to travel的更多相关文章
- hdu5893 List wants to travel(树链剖分+线段树)
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submissi ...
- 图论 - Travel
Travel The country frog lives in has nn towns which are conveniently numbered by 1,2,…,n. Among n(n− ...
- 【BZOJ-1576】安全路径Travel Dijkstra + 并查集
1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1044 Solved: 363[Sub ...
- Linux inode && Fast Directory Travel Method(undone)
目录 . Linux inode简介 . Fast Directory Travel Method 1. Linux inode简介 0x1: 磁盘分割原理 字节 -> 扇区(sector)(每 ...
- HDU - Travel
Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, he is t ...
- 2015弱校联盟(1) - I. Travel
I. Travel Time Limit: 3000ms Memory Limit: 65536KB The country frog lives in has n towns which are c ...
- ural 1286. Starship Travel
1286. Starship Travel Time limit: 1.0 secondMemory limit: 64 MB It is well known that a starship equ ...
- Travel Problem[SZU_K28]
DescriptionAfter SzuHope take part in the 36th ACMICPC Asia Chendu Reginal Contest. Then go to QingC ...
- hdu 5441 travel 离线+带权并查集
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Descript ...
随机推荐
- 基于Appium1.6.X的WebDriverAgent编译、安装
转自:http://www.cnblogs.com/baconLiu/p/6861431.html tips:WebDriverAgent是Appium1.6.3以后版本新添加的模块,为了让appiu ...
- 用VS2015编译sqlcipher
简介 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且目前已经在很多嵌 ...
- Language Modeling with Gated Convolutional Networks
语言模型 所谓的语言模型,即是指在得知前面的若干个单词的时候,下一个位置上出现的某个单词的概率. 最朴素的方法是N-gram语言模型,即当前位置只和前面N个位置的单词相关.如此,问题便是,N小了,语言 ...
- 四、正则表达式re模块
什么是正则表达式 正则表达式,又称规则表达式,通常被用来检索.替换那些符合某个模式(规则)的文本. 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一 ...
- [经典] 使用Python批量重命名iPhone拍摄的照片-按照拍摄时间重命名
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' 批量修改照片文件名称的Python脚本程序. 遍历指定目录(含子目录)的照片文件,根据拍照时间将照片 ...
- SQL查询练习一(From LeetCode)
请选用MySQL进行测试. 1.找出后一天比前一天温度高的日期(E) 思路:将该表进行自关联,然后选择出日期靠后的一天,最后选择温度高的日期 select Weather.Id from Weath ...
- Redis入门_上
Redis是基于内存的Key-Value数据库,包含Set.String.SortedSet.List.Hash等数据结构,可用于缓存.排名.爬虫去重等应用场景. 1.思维导图 2.安装与配置 2.1 ...
- 拥抱.NET Core系列:MemoryCache 缓存过期
在上一篇"拥抱.NET Core系列:MemoryCache 初识"中我们基本了解了缓存的添加.删除.获取,那么今天我们来看看缓存的过期机制.这里和上篇一样将把"Micr ...
- js创建数组的三个方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- iOS——系统提供的dispatch方法
// 后台执行: dispatch_async(dispatch_get_global_queue(0,0), ^{ // something }); // 主线程执行: dispatch_async ...