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 ...
随机推荐
- POJ置换群入门[3/3]
POJ 3270 Cow Sorting 题意: 一个序列变为升序,操作为交换两个元素,代价为两元素之和,求最小代价 题解: 看了黑书... 首先循环因子分解 一个循环完成的最小代价要么是循环中最小元 ...
- BZOJ 4004: [JLOI2015]装备购买 [高斯消元同余 线性基]
和前两(一)题一样,不过不是异或方程组了..... 然后bzoj的新数据是用来卡精度的吧..... 所有只好在模意义下做啦 只是巨慢无比 #include <iostream> #incl ...
- EntityFramework 实践 Overview
使用EntityFramework,是微软出的一个轻量级ORM框架,对于做一些小型的项目非常方便,几乎是零配置,以及对linq的支持,所以非常的易于使用,虽然已经使用EntityFramework很久 ...
- 《深入理解Java虚拟机》——Java内存区域与内存溢出异常
程序计数器(Program Counter Register):一块较小的内存空间,可看作是当前线程所执行的字节码的行号指示器.字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令 ...
- Win10无法使用小娜搜索本地应用问题的解决方案
小娜介绍 win10的Cortana小娜是一个功能非常强大的语音和搜索助手,用户可以通过小娜助手搜索任意的文件和应用软件,不过有用户发现win10的小娜搜索不到已安装的本地软件,那么win10小娜助手 ...
- 使用websocket实现在线聊天功能
很早以前为了快速达到效果,使用轮询实现了在线聊天功能,后来无意接触了socket,关于socket我的理解是进程间通信,首先要有服务器跟客户端,服务的启动监听某ip端口定位该进程,客户端开启socke ...
- php header解决跨域问题
header('Access-Control-Allow-Credentials:true'); header('Access-Control-Allow-Origin:http://wdjkj.co ...
- 脚本启用python虚拟环境
#!/bin/bash rm -rf /data/website/activities/virtualenvvirtualenv --no-site-packages -p python3 /data ...
- 【实用】需要收藏备用的JQuery代码片段
1 元素屏幕居中 jQuery.fn.center = function () { this.css("position","absolute"); this. ...
- B站标题/子标题/url爬取示例(requests+re)
#coding:utf-8 __author__ = "zhoumi" 3 import requests import re import urllib ''' 本文档目的在于获 ...