线段树合并+树上差分

题目链接(···) 「简单」「一般」——其实「一般」也只多一个离散化

考试时想法看>这里<

总思路:先存所有的操作,离散化,然后用树上差分解决修改,用权值线段树维护每个值的个数,最后dfs合并处理答案(先处理儿子,再合并自己和儿子,递归解决)

简单版当然不用离散话辣。

做了好几天,感觉自己傻了。

但是好像也不是这样的

事实上,这道题确实扩充了我对线段树的认识。

它它它还可以不存左右区间的啊?——一定是我太蒻了

先附样例以示敬意


Sample Input


Sample Output

我还是第一次见这么恐怖的样例

不过它也是我的救命稻草,让我骗了5分,这是之前的事

样例以1为根的巨树

还是能看下的

树上差分就是通过修改树上某些节点的值来修改一段区间值的方法,比较常用

比如我们需要加树上一个区间

想这样,加从3到4的区间,每个加1(加N也一样)

那么我们按照差分法,3++,4++,1--,2--

「公式」其实是 x+n ,y+n ,lca(x,y)-n ,father[lca(x,y)]-n

别告诉我你不会lca,虽然我也是刚学了实用的版本

结果是这样的

这一步很快的···

我们要的结果当然不是±1什么的,要的是1或0

所以下面就是dfs统计结果(‘=’号前是过程,‘=’后是结果)

仿佛得到了结果

这样我们就能够离线处理树上的区间加减

注意:只能是离线,N个修改,一次输出


线段树合并前面已经说过,这里不再细讲。

这个题仿佛对内存的限制很苛刻(我MLE 22 次,数过,想哭),所以线段树的节点一定要节约开空,只开最大值和左右儿子指针

//鬼知道我调了几天的是这个傻点

左右区间可以递归维护,不必要一定存在节点里,

也不必须在维护最大值时捆绑维护下标,查询时的O(NlogN)还是可以接受的

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <queue>
#define N 200001
#define B 2*N
#define logN 31
using namespace std;
struct ST{
int f,t,next;
};ST rs[B];
int tot=,fl[N],n,m,len;
void add(int f,int t){
rs[tot].f=f;
rs[tot].t=t;
rs[tot].next=fl[f];
fl[f]=tot;
tot++;
}
struct XDS{
XDS *lid,*rid;
int maxn;
XDS(){
lid=rid=NULL;
maxn=;
}
};XDS *root[N];
struct CON{
int x,y,z;
};CON q[N];
int val[N];
int fvind(int i){
return lower_bound(val,val+len,i)-val+;
}
inline void build(XDS *&n){
n=new XDS();
}
void add(XDS *&rt,int v,int k,int l,int r){
if(rt==NULL)build(rt);
if(l==r){
rt->maxn+=k;
return ;
}
int mid=(l+r)>>;
if(mid>=v){
add(rt->lid,v,k,l,mid);
}
else{
add(rt->rid,v,k,mid+,r);
}
if(rt->lid!=NULL){
rt->maxn = rt->lid->maxn;
}
if(rt->rid!=NULL&&
rt->maxn < rt->rid->maxn)
rt->maxn = rt->rid->maxn;
}
int dep[N],fa[N][logN],ln;
bool is_v[N];
struct Myqu{
int f,e;
int Q[N*];
void push(int k){
e++;
Q[e]=k;
}
int front(){
f++;
return Q[f];
}
bool empty(){
if(e==f)return true;
return false;
}
}qu;
void bfs(int k){
qu.push(k);
is_v[k]=;
while(!qu.empty()){
int f=qu.front();
for(int i=fl[f];i!=-;i=rs[i].next){
if(!is_v[rs[i].t]){
qu.push(rs[i].t);
is_v[rs[i].t]=;
fa[rs[i].t][]=f;
dep[rs[i].t]=dep[f]+;
for(int j=;j<=ln;j++) fa[rs[i].t][j]=fa[fa[rs[i].t][j-]][j-];
}
}
}
}
int lca(int a,int b){//cout<<a<<SP<<b<<endl;
if(dep[a]>dep[b])swap(a,b);
for(int i=ln;i>=;i--)
if(dep[fa[b][i]]>=dep[a]){
b=fa[b][i];
//cout<<" "<<b<<" Dep"<<dep[b]<<endl;
}
if(a==b) return b;
for(int i=ln;i>=;i--)
if(fa[a][i]!=fa[b][i]){
a=fa[a][i],b=fa[b][i];
}
return fa[a][];
}
XDS* merge(int l,int r,XDS *&a,XDS *&b){
if(a==NULL)return b;
if(b==NULL)return a;
if(l==r){
a->maxn =a->maxn+b->maxn;
delete b;
b=NULL;
return a;
}
int mid=(l+r)>>;//puts("midgot");
a->lid=merge(l,mid,a->lid,b->lid);//puts("Lid merge end");
a->rid=merge(mid+,r,a->rid,b->rid);
if(a->lid!=NULL){
a->maxn = a->lid->maxn;
}
if(a->rid!=NULL&&
a->rid->maxn > a->maxn)
a->maxn =a->rid->maxn;
return a;
}
int ffind(XDS *rt,int l,int r){
int mid=(l+r)>>;
if(rt==NULL)return -;
if(l==r)return l;
if(rt->lid==NULL&&rt->rid==NULL)return -;
if(rt->lid==NULL)return ffind(rt->rid,mid+,r);
if(rt->rid==NULL)return ffind(rt->lid,l,mid);
if(rt->lid->maxn>=rt->rid->maxn){
return ffind(rt->lid,l,mid);
}
else return ffind(rt->rid,mid+,r);
}
void getans(int k){
is_v[k]=;
for(int i=fl[k];i!=-;i=rs[i].next){
if(is_v[rs[i].t]){
getans(rs[i].t);
root[k]=merge(,len,root[k],root[rs[i].t]);
}
}
int q=ffind(root[k],,len);
if(q==-)dep[k]=;
else dep[k]=val[q-];
}
int du[N];
int main(){
int a,b,c,ro;
memset(fl ,-,sizeof fl);
scanf("%d%d",&n,&m);
ln=log2(n)+;
for(int i=;i<n;i++){
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
for(int i=;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
q[i].x=a ,q[i].y=b ,q[i].z=val[i-]=c;
du[a]++,du[b]++;
}
int maxn=-;
for(int i=;i<=n;i++){
if(du[i]>maxn){
ro=i;
maxn=du[i];
}
}
sort(val+,val+m);
len=unique(val,val+m)-val;
dep[ro]=;
bfs(ro);
for(int i=;i<=m;i++){
int Lca=lca(q[i].x,q[i].y),val=fvind(q[i].z);
add(root[Lca], val,-,,len);
add(root[fa[Lca][]],val,-,,len);
add(root[q[i].x] ,val, ,,len);
add(root[q[i].y] ,val, ,,len);
}
getans(ro);
for(int i=;i<=n;i++){
printf("%d\n",dep[i]);
}
return ;
}

Total Code

[洛谷P4556][BZOJ3307]雨天的尾巴-T3订正的更多相关文章

  1. 【洛谷P4556】 雨天的尾巴

    题面 题解 线段树合并 我们看到这道题目首先可以想到树上差分,然后\(dfs\)合并 发现题目让我们求的东西很好用线段树维护 于是可以想到线段树合并 全世界只有我写指针版动态开点线段树(大雾 如果你要 ...

  2. 洛谷P4556 雨天的尾巴(线段树合并)

    洛谷P4556 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...

  3. [洛谷P4556] 雨天的尾巴

    这道题可以用线段树合并做,网上的题解基本上都是线段树合并的. 但是为什么我就偏偏要用dsu on tree...... 题目传送门 dsu on tree的方法类似[CF1009F] Dominant ...

  4. [BZOJ3307] 雨天的尾巴(树上差分+线段树合并)

    [BZOJ3307] 雨天的尾巴(树上差分+线段树合并) 题面 给出一棵N个点的树,M次操作在链上加上某一种类别的物品,完成所有操作后,要求询问每个点上最多物品的类型. N, M≤100000 分析 ...

  5. 洛谷 P4556 [Vani有约会]雨天的尾巴 解题报告

    P4556 [Vani有约会]雨天的尾巴 题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒 ...

  6. [bzoj3307]雨天的尾巴_线段树合并

    雨天的尾巴 bzoj-3307 题目大意:N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. ...

  7. 洛谷P4556 [Vani有约会]雨天的尾巴(线段树合并)

    题目背景 深绘里一直很讨厌雨天. 灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切. 虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连根拔起,以及田地 ...

  8. 洛谷P4556 雨天的尾巴 线段树

    正解:线段树合并 解题报告: 传送门! 考虑对树上的每个节点开一棵权值线段树,动态开点,记录一个max(num,id)(这儿的id,define了一下,,,指的是从小到大排QAQ 然后修改操作可以考虑 ...

  9. 2018.08.28 洛谷P4556 [Vani有约会]雨天的尾巴(树上差分+线段树合并)

    传送门 要求维护每个点上出现次数最多的颜色. 对于每次修改,我们用树上差分的思想,然后线段树合并统计答案就行了. 注意颜色很大需要离散化. 代码: #include<bits/stdc++.h& ...

随机推荐

  1. 为什么用思科里面的设备第一次ping的时候总会丢一个包呢?

    大家搞计算机的不用讲,肯定都玩过网络吧?   比如一些思科,华为,华三这些模拟器,你们总会当你第一次用某个设备去ping某个设备的时候第一包总会被丢弃.  但我相信很多人都不知道为啥 会丢弃. 今天小 ...

  2. PHP中正则表达式学习及应用(三)

    正则表达式中的“模式修正符” 1.运算顺序    2.模式修正符 i 正则内容在匹配时候不区分大小写(默认是区分的) 例如: <?php $mode="/[a-z]/i"; ...

  3. html css鼠标样式,鼠标形状

    css鼠标手型cursor中hand与pointer Example:CSS鼠标手型效果 <a href="#" style="cursor:hand"& ...

  4. Weekly Contest 111-------->942. DI String Match

    Given a string S that only contains "I" (increase) or "D" (decrease), let N = S. ...

  5. 658. Find K Closest Elements

    Given a sorted array, two integers k and x, find the k closest elements to x in the array. The resul ...

  6. lightoj1060【康托逆展开】

    可以先看些资料:http://blog.csdn.net/keyboarderqq/article/details/53388936 参考谷巨巨:http://blog.csdn.net/azx736 ...

  7. GoldenGate对接 mysql

    环境: centos 7.4 mysql 5.5.58 glibc 64 位版,下载链接:https://dev.mysql.com/downloads/mysql/5.5.html#download ...

  8. Spring Boot后端+Vue前端+微信小程序,完整的开源解决方案!

    项目简介 一个小商场系统,包括: 后端:Spring Boot 管理员前端:Vue 用户前端:微信小程序 功能介绍 1.小商城 首页 专题列表.专题详情 分类列表.分类详情 品牌列表.品牌详情 新品首 ...

  9. 设置导航栏 self.navigationItem.titleView 居中

    喜欢交朋友的加:微信号 dwjluck2013-(void)viewDidLayoutSubviews{ [self setDisplayCustomTitleText:@"每日头条&quo ...

  10. UVA297:Quadtrees(四分树)

    题目描述 四象树是每个内结点均有4个子结点的特殊四叉树,它可用于描述平面上黑白图像.平面上的黑白图像是32行×32列的正方形,每个格子称为1个象素,是最小的图像单位.正方形图像可分成四个相等的小正方形 ...