洛谷P4374 [USACO18OPEN]Disruption(树链剖分+线段树)

传送门

 

不难发现,每一条额外修的路径,会对原树上$(u,v)$路径上的所有边产生贡献

于是这就变成了一个路径修改

那么我们把每一条边赋值到它连接的两个点中深度较大的那个上面,然后每一次用树剖+线段树做路径修改,然后再把权值取回来就行了

几个注意点:

1.记得路径修改的时候$LCA$是不需要改的

2.区间修改要打标记,统计答案之前先把标记全都放掉

3.一个小技巧就是把边从2开始存,这样双向边标号就分别是$(2,3),(4,5)...$,于是每一条双向边的标号除以二都是唯一的,就可以唯一的表示出来

 1 //minamoto
 2 #include<bits/stdc++.h>
 3 #define inf 0x3f3f3f3f
 4 using namespace std;
 5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 6 char buf[1<<21],*p1=buf,*p2=buf;
 7 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
 8 inline int read(){
 9     #define num ch-'0'
10     char ch;bool flag=0;int res;
11     while(!isdigit(ch=getc()))
12     (ch=='-')&&(flag=true);
13     for(res=num;isdigit(ch=getc());res=res*10+num);
14     (flag)&&(res=-res);
15     #undef num
16     return res;
17 }
18 char sr[1<<21],z[20];int C=-1,Z;
19 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
20 inline void print(int x){
21     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
22     while(z[++Z]=x%10+48,x/=10);
23     while(sr[++C]=z[Z],--Z);sr[++C]='\n';
24 }
25 const int N=50005;
26 int head[N],ver[N<<1],Next[N<<1],tot=1;
27 inline void add(int u,int v){
28     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
29 }
30 int num[N],val[N],bl[N],dfn[N],sz[N],fa[N],dep[N],son[N],top[N],cnt,n,m;
31 void dfs1(int u){
32     sz[u]=1,dep[u]=dep[fa[u]]+1;
33     for(int i=head[u];i;i=Next[i]){
34         int v=ver[i];
35         if(v!=fa[u]){
36             fa[v]=u,num[v]=i>>1,dfs1(v),sz[u]+=sz[v];
37             if(sz[son[u]]<sz[v]) son[u]=v;
38         }
39     }
40 }
41 void dfs2(int u,int t){
42     top[u]=t,dfn[u]=++cnt,bl[cnt]=u;
43     if(son[u]){
44         dfs2(son[u],t);
45         for(int i=head[u];i;i=Next[i]){
46             int v=ver[i];
47             if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
48         }
49     }
50 }
51 int mn[N<<2],tag[N<<2];
52 #define ls (p<<1)
53 #define rs (p<<1|1)
54 inline void upd(int p){mn[p]=min(mn[ls],mn[rs]);}
55 inline void pd(int p){
56     if(tag[p]!=inf){
57         cmin(tag[ls],tag[p]),cmin(tag[rs],tag[p]);
58         cmin(mn[ls],tag[p]),cmin(mn[rs],tag[p]);
59         tag[p]=inf;
60     }
61 }
62 void update(int p,int l,int r,int ql,int qr,int x){
63     if(ql<=l&&qr>=r) return (void)(cmin(tag[p],x),cmin(mn[p],x));
64     int mid=(l+r)>>1;pd(p);
65     if(ql<=mid) update(ls,l,mid,ql,qr,x);
66     if(qr>mid) update(rs,mid+1,r,ql,qr,x);
67     upd(p);
68 }
69 void query(int p,int l,int r){
70     if(l==r) return (void)(val[num[bl[l]]]=mn[p]);
71     int mid=(l+r)>>1;pd(p);
72     query(ls,l,mid),query(rs,mid+1,r);
73 }
74 void change(int u,int v,int x){
75     while(top[u]!=top[v]){
76         if(dep[top[u]]<dep[top[v]]) swap(u,v);
77         update(1,1,n,dfn[top[u]],dfn[u],x);
78         u=fa[top[u]];
79     }
80     if(u==v) return;
81     if(dep[u]<dep[v]) swap(u,v);
82     update(1,1,n,dfn[son[v]],dfn[u],x);
83 }
84 int main(){
85 //    freopen("testdata.in","r",stdin);
86     n=read(),m=read();
87     for(int i=1,u,v;i<n;++i)
88     u=read(),v=read(),add(u,v),add(v,u);
89     memset(mn,0x3f,sizeof(mn)),memset(tag,0x3f,sizeof(tag));
90     dfs1(1),dfs2(1,1);
91     while(m--){
92         int u=read(),v=read(),e=read();
93         change(u,v,e);
94     }
95     query(1,1,n);
96     for(int i=1;i<n;++i) print(val[i]==inf?-1:val[i]);
97     Ot();
98     return 0;
99 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9794778.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值