bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】
这居然是我第一次写线段树合并……所以我居然在合并的时候加点结果WAWAWAMLEMLEMLE……!ro的时候居然直接指到la就行……
树上差分,每个点建一棵动态开点线段树,然后统计答案的时候合并即可
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=100005;
int n,m,h[N],cnt,de[N],fa[N],si[N],hs[N],fr[N],c[N],rt[N],tot,ans[N],d[N];
struct qwe
{
int ne,to;
}e[N<<1];
struct xds
{
int ls,rs,mx,p;
}t[7500005];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void add(int u,int v)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
h[u]=cnt;
}
void dfs1(int u,int fat)
{
fa[u]=fat;
de[u]=de[fat]+1;
si[u]=1;
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=fat)
{
dfs1(e[i].to,u);
d[u]++;
si[u]+=si[e[i].to];
if(si[e[i].to]>si[hs[u]])
hs[u]=e[i].to;
}
}
void dfs2(int u,int top)
{
fr[u]=top;
if(!hs[u])
return;
dfs2(hs[u],top);
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=fa[u]&&e[i].to!=hs[u])
dfs2(e[i].to,e[i].to);
}
int lca(int u,int v)
{//cerr<<u<<" "<<v<<endl;
for(;fr[u]!=fr[v];de[fr[u]]>de[fr[v]]?u=fa[fr[u]]:v=fa[fr[v]]);
return de[u]<de[v]?u:v;
}
void ud(int ro)
{
if(t[ro].ls&&t[t[ro].ls].mx>=t[t[ro].rs].mx)
t[ro].p=t[t[ro].ls].p,t[ro].mx=t[t[ro].ls].mx;
else
t[ro].p=t[t[ro].rs].p,t[ro].mx=t[t[ro].rs].mx;
}
void update(int &ro,int l,int r,int p,int v)
{
if(!ro)
ro=++tot,t[ro].p=l;
if(l==r)
{//cerr<<p<<" "<<v<<" "<<t[ro].mx<<endl;
t[ro].mx+=v;
return;
}
int mid=(l+r)>>1;
if(p<=mid)
update(t[ro].ls,l,mid,p,v);
else
update(t[ro].rs,mid+1,r,p,v);
ud(ro);
}
void hb(int &ro,int la,int l,int r)
{
if(!la)
return;
if(!ro)
{
ro=la;
return;
}
if(l==r)
{
t[ro].mx+=t[la].mx;
return;
}
int mid=(l+r)>>1;
hb(t[ro].ls,t[la].ls,l,mid);
hb(t[ro].rs,t[la].rs,mid+1,r);
ud(ro);
}
// void dfs(int u)
// {
// for(int i=h[u];i;i=e[i].ne)
// if(e[i].to!=fa[u])
// {
// dfs(e[i].to);
// hb(rt[u],rt[e[i].to],1,100000);
// }
// if(t[rt[u]].mx<=0)
// ans[u]=0;
// else
// ans[u]=t[rt[u]].p;//cerr<<u<<" "<<t[rt[u]].mx<<endl;
// }
int main()
{
n=read(),m=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
add(x,y),add(y,x);
}
dfs1(1,0);
dfs2(1,1);
t[0].mx=-1e9;
while(m--)
{
int x=read(),y=read(),z=read(),lc=lca(x,y);
update(rt[x],1,100000,z,1);
update(rt[y],1,100000,z,1);
update(rt[lc],1,100000,z,-1);
if(fa[lc])
update(rt[fa[lc]],1,100000,z,-1);
// cerr<<t[rt[x]].p<<" "<<t[rt[x]].mx<<" "<<t[rt[y]].p<<" "<<t[rt[y]].mx<<" "<<t[rt[lc]].p<<" "<<t[rt[lc]].mx<<" "<<t[rt[fa[lc]]].p<<" "<<t[rt[fa[lc]]].mx<<" "<<endl;
}
// dfs(1);
queue<int>q;
for(int i=1;i<=n;i++)
if(!d[i])
q.push(i);
while(!q.empty())
{
int u=q.front();//cerr<<u<<endl;
q.pop();
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=fa[u])
hb(rt[u],rt[e[i].to],1,100000);
if(t[rt[u]].mx<=0)
ans[u]=0;
else
ans[u]=t[rt[u]].p;
if(!(--d[fa[u]]))
q.push(fa[u]);
}
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}
bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】的更多相关文章
- Bzoj 3307 雨天的尾巴(线段树合并+树上差分)
C. 雨天的尾巴 题目描述 N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式 第 ...
- [BZOJ3307] 雨天的尾巴(树上差分+线段树合并)
[BZOJ3307] 雨天的尾巴(树上差分+线段树合并) 题面 给出一棵N个点的树,M次操作在链上加上某一种类别的物品,完成所有操作后,要求询问每个点上最多物品的类型. N, M≤100000 分析 ...
- [Luogu5327][ZJOI2019]语言(树上差分+线段树合并)
首先可以想到对每个点统计出所有经过它的链的并所包含的点数,然后可以直接得到答案.根据实现不同有下面几种方法.三个log:假如对每个点都存下经过它的链并S[x],那么每新加一条路径进来的时候,相当于在路 ...
- BZOJ 3307: 雨天的尾巴( LCA + 线段树合并 )
路径(x, y) +z : u处+z, v处+z, lca(u,v)处-z, fa(lca)处-z, 然后dfs一遍, 用线段树合并. O(M log M + M log N). 复杂度看起来不高, ...
- BZOJ.3307.雨天的尾巴(dsu on tree/线段树合并)
BZOJ 洛谷 \(dsu\ on\ tree\).(线段树合并的做法也挺显然不写了) 如果没写过\(dsu\)可以看这里. 对修改操作做一下差分放到对应点上,就成了求每个点子树内出现次数最多的颜色, ...
- BZOJ 3307 雨天的尾巴 (树上差分+线段树合并)
题目大意:给你一棵树,树上一共n个节点,共m次操作,每次操作给一条链上的所有节点分配一个权值,求所有节点被分配到所有的权值里,出现次数最多的权值是多少,如果出现次数相同就输出最小的. (我辣鸡bzoj ...
- bzoj 3307: 雨天的尾巴 线段树合并
题目大意: N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.问完成所有发放后,每个点存放最多的是哪种物品. 题解: 首先我们为每一个节 ...
- bzoj 3307 雨天的尾巴
题目链接:传送门 题目大意:中文题,略 题目思路:网上有题解说是合并线段树的,但是太难蒟蒻不会,只能用树剖求解 如果不是树而是一维数组我们会怎么解? 当然是利用前缀和思想标记 (L) v+1,(R+1 ...
- [Vani有约会]雨天的尾巴(树上差分+线段树合并)
首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋z类型的救济粮. 然后深绘里想知道,当所有的救济粮 ...
随机推荐
- 解决idea中启动tomcat出现控制台乱码问题
尝试了很多方法,最后终于解决了,现在提供给大家一个我认为最简单也最有效的方案. 1.修改配置文件 找到idea的安装目录,在bin文件夹下找到以下两个文件,用记事本或者其他软件打开: 然后两个文件中都 ...
- Access to Image at 'file:///Users canvas本地图片跨域报错解决方案
1.设置跨域 添加跨域条件 crossorigin="anonymous" 前提是后端支持这个图片跨域 2.上面加了之后还是报错 如标题所示 你需要把你的项目放到服务器上面跑 ...
- WebLogic中"域"的概念
WebLogic 版权声明:本文为博主原创文章,未经博主允许不得转载. WebLogic Server中的域是逻辑上相关的一组 WebLogic Server 资源,可以作为一个单元进行管理.一个域中 ...
- JAVA原始的导出excel文件,快捷通用 方便 还能够导出word文档哦
如今导出excel基本上都是用poi了,当报表格式非常负责的时候 开发难度会加大 假设报表有格式有变化 那就更复杂了,先发现一个非常老的技术.能够解决格式复杂的报表. 实例代码例如以下: <%@ ...
- 选带傅里叶变换(zoom-fft)
选带傅里叶变换的原理大家能够看书.大致的步骤为 移频 (将选带的中心频率移动到零频) 数字低通滤波器 (防止频率混叠) 又一次採样 (将採样的数据再次间隔採样,间隔的数据取决于分析的带宽,就是放大 ...
- coco2d-x怎样创建project
不知道coco2d-x从那个版本号開始用python创建project,一句话搞定,确实省去了好多麻烦. 首先定位到coco2d-x的文件夹到cocos2d-x-2.2.3\cocos2d-x-2.2 ...
- Sublime Text 3.3143最新注册码
Sublime Text3之前用的是老版本,昨天手贱点了更新,就要重新激活,网上找了好多都是之前版本的,以下给干货 —– BEGIN LICENSE —– TwitterInc User Licens ...
- Android Material Design-Maintaining Compatibility(保持兼容性)-(七)
转载请注明出处:http://blog.csdn.net/bbld_/article/details/40634829 翻译自: http://developer.android.com/traini ...
- Servlet访问Javabean并传结果给jsp
1.先建立包名: 2.建立实体类 参考二维表,考虑各个字段名字.类型 在entity包里面建立一个类,代码如下: public class House { private String id; pri ...
- 微信企业号调用js-sdk注意事项
企业号应用必须添加可信域名,域名必须通过备案,可以是子域名,如果网站带端口,一定也要加上端口号...踩坑记