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 ...
随机推荐
- 《Thinking in Java》学习笔记(五)
1. Java异常补充 a.使用try/catch捕获了异常之后,catch之后的代码是会正常运行的,认为即使进行了异常捕获,出现了异常就不往下执行,这是很多新手会犯的错误. public class ...
- Win10无法使用小娜搜索本地应用问题的解决方案
小娜介绍 win10的Cortana小娜是一个功能非常强大的语音和搜索助手,用户可以通过小娜助手搜索任意的文件和应用软件,不过有用户发现win10的小娜搜索不到已安装的本地软件,那么win10小娜助手 ...
- 极大似然估计(MLE)
基本思想 模型已定,参数未知 根据已存在的样本,挑选(求出)能让样本以最大概率发生的参数 极大似然估计和最小二乘法最大区别之一 极大似然需要知道概率密度函数(离散型叫分布律) 若总体X属离散型,其分布 ...
- 集合的综合练习:Poker牌
/* 刘意教程示例:*/ package cn.onecool.cot; import java.util.ArrayList; import java.util.Collections; impor ...
- linux集群架构
Linux集群架构 根据功能划分为两大类:高可用和负载均衡 高可用集群通常为两台服务器,一台工作,另外一台作为冗余,当提供服务的机器宕机,冗余将接替继续提供服务 实现高可用的开源软件有:heart ...
- curl模拟请求
GET请求 <?php //初始化 $curl = curl_init(); //设置抓取的url curl_setopt($curl, CURLOPT_URL, 'http://www.bai ...
- ng-csv 异步数据下载
相信很多码友遇到一个很坑的问题吧,就是使用ng-csv 的时候 lazy-load="true" 设置为true 还是 会下载0行数据 var getArray= functio ...
- 初识vue——起步
一.目录结构: 我们经常使用的是以下几个目录: 1.assets:静态资产文件:在vue组件中,所有组件中,所有模板和CSS都会被vue-html-loader和css-loader解析,并查找资源u ...
- Python 上下文管理器和else块
最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的 ...
- SIFT解析(三)生成特征描述子
以上两篇文章中检测在DOG空间中稳定的特征点,lowe已经提到这些特征点是比Harris角点等特征还要稳定的特征.下一步骤我们要考虑的就是如何去很好地描述这些DOG特征点. 下面好好说说如何来描述这些 ...