hdu5893 List wants to travel(树链剖分+线段树)
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 270 Accepted Submission(s): 47
Can you help him? (He is so lazy to do this by himself.)
bidirectionoal road between city a and city b, and the cost is c.(a != b and c <= 100000). Then there are M lines of operation. For example, "Change a b c" means changing all the costs of the road which are passed by him when he travels from city a to city
b to c. "Query a b" means he wants you to tell him how many different kinds of continuous same cost he has to pay traveling from city a to city b.(if a == b, the cost is 0).
1 2 2
2 3 1
1 7 2
1 4 2
3 5 2
3 6 1
5 8 2
5 9 3
Query 1 8
Change 2 6 3
Query 1 6
2
题意:和bzoj2243题目几乎一样,区别在于bzoj颜色在点上,这题颜色在边上。
思路:先树链剖分,然后用线段树维护num(不同颜色的段数),cl(线段左端点的颜色),cr(线段右端点的颜色),然后因为处理的是线段,所以这里要把线段上的颜色当成这条线段连接的两个点深度更大的点的颜色,然后就和bzoj2243一样了。比赛的时候记得这题,但是因为是线段上的颜色,就不会了,亥,还是太弱了。。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 999999999
#define pi acos(-1.0)
#define maxn 40010
#define maxm 50050
struct edge{
int to,next,len;
}e[2*maxm];
int pos,tot,Lc,Rc;
int top[maxn],son[maxn],fa[maxn],dep[maxn],num[maxn],p[maxn],a[maxn],c[maxn],first[maxn];
void dfs1(int u,int pre,int deep)
{
int i,j,v;
dep[u]=deep;
fa[u]=pre;
num[u]=1;
for(i=first[u];i!=-1;i=e[i].next){
v=e[i].to;
if(v==pre)continue;
a[v]=e[i].len;
dfs1(v,u,deep+1);
num[u]+=num[v];
if(son[u]==-1 || num[son[u] ]<num[v]){
son[u]=v;
}
}
}
void dfs2(int u,int tp)
{
int i,j,v;
top[u]=tp;
if(son[u]!=-1){
p[u]=++pos;
c[pos]=a[u];
dfs2(son[u],tp);
}
else{
p[u]=++pos;
c[pos]=a[u];
return;
}
for(i=first[u];i!=-1;i=e[i].next){
v=e[i].to;
if(v==son[u] || v==fa[u])continue;
dfs2(v,v);
}
}
struct node{
int l,r,num,cl,cr,flag;
}b[4*maxn];
void pushup(int th)
{
b[th].cl=b[lson].cl;
b[th].cr=b[rson].cr;
b[th].num=b[lson].num+b[rson].num;
if(b[lson].cr==b[rson].cl)b[th].num--;
}
void pushdown(int th)
{
if(b[th].flag==1){
b[lson].flag=b[rson].flag=1;
b[lson].cl=b[lson].cr=b[rson].cl=b[rson].cr=b[th].cl;
b[lson].num=b[rson].num=1;
b[th].flag=-1;
}
}
void build(int l,int r,int th)
{
int mid;
b[th].l=l;b[th].r=r;
b[th].flag=-1;
if(l==r){
b[th].cl=b[th].cr=c[l];
b[th].num=1;
return;
}
mid=(b[th].l+b[th].r)/2;
build(l,mid,lson);
build(mid+1,r,rson);
pushup(th);
}
void update(int l,int r,int color,int th)
{
int mid;
if(b[th].l==l && b[th].r==r){
b[th].num=1;
b[th].flag=1;
b[th].cl=b[th].cr=color;
return;
}
pushdown(th);
mid=(b[th].l+b[th].r)/2;
if(r<=mid)update(l,r,color,lson);
else if(l>mid)update(l,r,color,rson);
else{
update(l,mid,color,lson);
update(mid+1,r,color,rson);
}
pushup(th);
}
int question(int l,int r,int th,int L,int R)
{
int mid,num;
if(b[th].l==L)Lc=b[th].cl;
if(b[th].r==R)Rc=b[th].cr;
if(b[th].l==l && b[th].r==r){
return b[th].num;
}
pushdown(th);
mid=(b[th].l+b[th].r)/2;
if(r<=mid)return question(l,r,lson,L,R);
else if(l>mid)return question(l,r,rson,L,R);
else{
num=question(l,mid,lson,L,R)+question(mid+1,r,rson,L,R);
if(b[lson].cr==b[rson].cl)num--;
return num;
}
}
int solve(int u,int v)
{
int f1,f2;
f1=top[u];f2=top[v];
int num=0,pre1,pre2;
pre1=pre2=-1;
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(pre1,pre2);swap(f1,f2);swap(u,v);
}
num+=question(p[f1],p[u],1,p[f1],p[u]);
if(pre1==Rc)num--;
pre1=Lc;
u=fa[f1];
f1=top[u];
}
if(u!=v){
if(dep[u]<dep[v]){
swap(pre1,pre2);swap(u,v);
}
num+=question(p[son[v]],p[u],1,p[son[v]],p[u]);
if(pre1!=-1 && Rc==pre1)num--;
if(pre2!=-1 && Lc==pre2)num--;
}
else if(pre1==pre2)num--;
return num;
}
void gengxin(int u,int v,int value)
{
int f1,f2;
f1=top[u];f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]){
swap(f1,f2);swap(u,v);
}
update(p[f1],p[u],value,1);
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v]){
swap(u,v);
}
if(u!=v){
update(p[son[v]],p[u],value,1);
}
}
void add(int u,int v,int len)
{
tot++;
e[tot].next=first[u];e[tot].to=v;e[tot].len=len;
first[u]=tot;
}
int main()
{
int i,j,n,m,u,v,f,g,h,w;
char s[10];
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(first,-1,sizeof(first));
memset(son,-1,sizeof(son));
pos=0;tot=0;
for(i=1;i<=n-1;i++){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);add(v,u,w);
}
dfs1(1,0,1);
dfs2(1,1);
build(1,pos,1);
for(i=1;i<=m;i++){
scanf("%s",s);
if(s[0]=='Q'){
scanf("%d%d",&f,&g);
printf("%d\n",solve(f,g));
}
else{
scanf("%d%d%d",&f,&g,&h);
gengxin(f,g,h);
}
}
}
return 0;
}
hdu5893 List wants to travel(树链剖分+线段树)的更多相关文章
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
随机推荐
- Databricks 第5篇:Databricks文件系统(DBFS)
Databricks 文件系统 (DBFS,Databricks File System) 是一个装载到 Azure Databricks 工作区的分布式文件系统,可以在 Azure Databric ...
- Debian安装HomeBrew
前言 HomeBrew 的用处我想使用 Mac 的开发人员都知道, 本篇讲解如何在 Debian 上安装 BrewLinux 更新: 后来发现并不是很好用, 不建议使用 官方推荐的脚本安装 注意这里只 ...
- 【剑指 Offer】05.替换空格
题目描述 请实现一个函数,把字符串 s 中的每个空格替换成"%20". 示例 1: 输入:s = "We are happy." 输出:"We%20a ...
- 最全的HashMap源码解析!
HashMap源码解析 HashMap采用键值对形式的存储结构,每个key对应唯一的value,查询和修改的速度很快,能到到O(1)的平均复杂度.他是非线程安全的,且不能保证元素的存储顺序. 他的关系 ...
- /usr/local/mysql/bin/mysqlbinlog -vv /var/lib/bin/mysql-bin.000008 --base64-output=DECODE-ROWS --start-pos=307
/usr/local/mysql/bin/mysqlbinlog -vv /var/lib/bin/mysql-bin.000008 --base64-output=DECODE-ROWS --st ...
- vmstat参数详解
vmstat 5 可以使用ctrl+c停止vmstat,可以看到输出依赖于所用的操作系统,因此可能需要阅读一下手册来解读报告 第一行的值是显示子系统启动以来的平均值,第二行开始展示现在正在发生的情况, ...
- Linux三剑客grep、awk和sed
grep,sed 和 awk是Linux/Unix 系统中常用的三个文本处理的命令行工具,称为文本处理三剑客.本文将简要介绍这三个命令并给出基本用法. 管道 在介绍这两个命令之前,有必要介绍一下Uni ...
- AmoebaNet:经费在燃烧,谷歌提出基于aging evolution的神经网络搜索 | AAAI 2019
论文提出aging evolution,一个锦标赛选择的变种来优化进化算法,在NASNet搜索空间上,对比强化学习和随机搜索,该算法足够简洁,而且能够更快地搜索到更高质量的模型,论文搜索出的Amoeb ...
- oracle rac切换到单实例DG后OGG的处理
在RAC切换到单实例DG后,将OGG目录复制过去,在使用alter extract ext_name,begin now的时候报错 2016-04-10 11:27:03 WARNING OGG-01 ...
- Sentry(v20.12.1) K8S 云原生架构探索,1分钟上手 JavaScript 性能监控
系列 Sentry-Go SDK 中文实践指南 一起来刷 Sentry For Go 官方文档之 Enriching Events Snuba:Sentry 新的搜索基础设施(基于 ClickHous ...