传送门

1A此题暴祭

(下面记点\(x\)深度为\(de_x\),某个时间点记为\(w_x\))

首先,每条路径是可以拆成往上和往下两条路径的

对于往上的路径,假设有个人往上跑,\(w_y\)在点\(y\),那么如果能对点\(x\)的观察员产生贡献,当且仅当\(w_x+de_x=w_y+de_y\)

对于往下的路径,假设有个人往下跑,\(w_y\)在点\(y\),那么如果能对点\(x\)的观察员产生贡献,当且仅当\(w_x-de_x=w_y-de_y\)

所以对于每个点开两个线段树,每个下表存\(w_x+de_x\)或\(w_x-de_x\)的点的个数,对于每条路径(x,y),记\(len\)为路径长度(结束时间点),\(mid\)为到达\(lca\)的时间,在\(x\)的第一个线段树的\(de_x\)处+1,在\(lca\)的第一个线段树的\(mid+de_{lca}\)处-1,在y的第二个线段树的\(len-de_y+n\)处+1,在\(fa_{lca}\)的第二个线段树的\(mid-1-de_{fa_{lca}}+n\)处-1(不能出现负下标).dfs整棵树,把\(x\)所有儿子的线段树并起来,然后这个点的答案就是第一棵线段树的\(w_x+de_x\)加第二棵线段树的\(w_x-de_x+n\)的值

我太傻了,这两颗线段树可以分开处理的,我放在一起处理了,空间爆炸,bzoj就过不去了qwq

#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
#define eps (1e-5) using namespace std;
const int N=300000+10;
il LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N<<1],nt[N<<1],hd[N],tot=1;
il void add(int x,int y)
{
++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
}
int n,m,w[N],an[N],fa[N],sz[N],de[N],son[N],top[N];
void dfs1(int x)
{
sz[x]=1;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
fa[y]=x,de[y]=de[x]+1,dfs1(y),sz[x]+=sz[y];
if(sz[son[x]]<sz[y]) son[x]=y;
}
}
void dfs2(int x,int ntp)
{
top[x]=ntp;
if(son[x]) dfs2(son[x],ntp);
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
il int glca(int x,int y)
{
while(top[x]!=top[y])
{
if(de[top[x]]<de[top[y]]) swap(x,y);
x=fa[top[x]];
}
return de[x]<de[y]?x:y;
}
struct sgtree
{
int s[(N*3)*20],ch[(N*3)*20][2],rt[N],tt;
sgtree(){tt=0;}
il void inst(int o1,int o2,int x,int dt)
{
int l=1,r=n+n;
s[o1]=s[o2]+dt;
while(l<r)
{
int mid=(l+r)>>1;
if(x<=mid)
{
ch[o1][0]=++tt,ch[o1][1]=ch[o2][1];
o1=ch[o1][0],o2=ch[o2][0];
r=mid;
}
else
{
ch[o1][0]=ch[o2][0],ch[o1][1]=++tt;
o1=ch[o1][1],o2=ch[o2][1];
l=mid+1;
}
s[o1]=s[o2]+dt;
}
}
int merge(int o1,int o2)
{
if(!o1||!o2) return o1+o2;
int o=++tt;
s[o]=s[o1]+s[o2];
ch[o][0]=merge(ch[o1][0],ch[o2][0]);
ch[o][1]=merge(ch[o1][1],ch[o2][1]);
return o;
}
int quer(int o,int l,int r,int lx)
{
if(!o) return 0;
if(l==r) return s[o];
int mid=(l+r)>>1;
if(lx<=mid) return quer(ch[o][0],l,mid,lx);
else return quer(ch[o][1],mid+1,r,lx);
}
}S,T;
il void dfs3(int x)
{
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
dfs3(y),S.rt[x]=S.merge(S.rt[x],S.rt[y]),T.rt[x]=T.merge(T.rt[x],T.rt[y]);
}
an[x]=S.quer(S.rt[x],1,n+n,w[x]+de[x])+T.quer(T.rt[x],1,n+n,w[x]-de[x]+n);
} int main()
{
n=rd(),m=rd();
for(int i=1;i<n;i++) add(rd(),rd());
de[1]=1,dfs1(1),dfs2(1,1);
for(int i=1;i<=n;i++) w[i]=rd();
while(m--)
{
int x=rd(),y=rd(),lca=glca(x,y),lth=de[x]+de[y]-(de[lca]<<1),mid=lth-de[y]+de[lca],la;
la=S.rt[x],S.rt[x]=++S.tt,S.inst(S.rt[x],la,de[x],1);
la=S.rt[lca],S.rt[lca]=++S.tt,S.inst(S.rt[lca],la,de[lca]+mid,-1);
la=T.rt[y],T.rt[y]=++T.tt,T.inst(T.rt[y],la,lth-de[y]+n,1);
la=T.rt[fa[lca]],T.rt[fa[lca]]=++T.tt,T.inst(T.rt[fa[lca]],la,mid-1-de[fa[lca]]+n,-1);
}
dfs3(1);
for(int i=1;i<=n;i++) printf("%d ",an[i]);
return 0;
}

luogu P1600 天天爱跑步的更多相关文章

  1. [NOIP 2016D2T2/Luogu P1600] 天天爱跑步 (LCA+差分)

    待填坑 Code //Luogu P1600 天天爱跑步 //Apr,4th,2018 //树上差分+LCA #include<iostream> #include<cstdio&g ...

  2. [luogu]P1600 天天爱跑步[LCA]

    [luogu]P1600 [NOIP 2016]天天爱跑步 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上 ...

  3. 洛谷P1600 天天爱跑步(线段树合并)

    小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn ...

  4. P1600 天天爱跑步[桶+LCA+树上差分]

    题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵 ...

  5. Luogu:P1600 天天爱跑步

    来一发清新的80行 树剖 $LCA$ + 树上差分 题解. -----from Judge 本题题意大概是给出一棵 n 个节点的树以及 m 条有向路径, 并且每个点 i 都有一个权值 $w[i]$,如 ...

  6. 洛谷 P1600 天天爱跑步

    https://www.luogu.org/problemnew/show/P1600 (仅做记录) 自己的假方法: 每一次跑从a到b:设l=lca(a,b)对于以下产生贡献: a到l的链上所有的点( ...

  7. 洛谷P1600 天天爱跑步——树上差分

    题目:https://www.luogu.org/problemnew/show/P1600 看博客:https://blog.csdn.net/clove_unique/article/detail ...

  8. 洛谷P1600 天天爱跑步

    天天放毒... 首先介绍一个树上差分. 每次进入的时候记录贡献,跟出来的时候的差值就是子树贡献. 然后就可以做了. 发现考虑每个人的贡献有困难. 于是考虑每个观察员的答案. 把路径拆成两条,以lca分 ...

  9. P1600 天天爱跑步

    lca真心不太会,这里只介绍60分做法,100的太难辣简单了就不介绍了 n<=1000 zz回溯爆搜 S[i]全部相等 这dfs序都不用lca的,2333,差分,然后输出判断一下是否是0(1到i ...

随机推荐

  1. Security Testing Test Scenarios

    1 check for sql injection attacks2 secure pages should use https protocol3 page crash should not rev ...

  2. windows部分常用命令

    dir 查看内容 md 新建目录 copy 复制 del 删文件 cls 清屏 tasklist 查看运行进程 taskkill /pid xxx 杀死进程xxx taskmgr 打开任务管理器 ms ...

  3. mybatis 缓存(cache)的使用

    许多应用程序,为了提高性能而增加缓存, 特别是从数据库中获取的数据. 在默认情况下,mybatis 的一级缓存是默认开启的.类似于hibernate, 所谓一级缓存,也就是基于同一个sqlsessio ...

  4. 因为代理原因导致的NotSerializableException

    错误信息: NotSerializableException Failed to serialize object Proxy   报这个错,一开始就往没有序列化这一块想,可是报错点是: excelT ...

  5. 自学Linux Shell7.3-linux共享文件

    点击返回 自学Linux命令行与Shell脚本之路 7.3-linux共享文件 在linux系统中共享文件的方法是通过创建组. 1. linux为每个文件和目录存储了3个额外的信息位: SUID设置用 ...

  6. 【BZOJ4161】Shlw loves matrixI (常系数齐次线性递推)

    [BZOJ4161]Shlw loves matrixI (常系数齐次线性递推) 题面 BZOJ 题解 \(k\)很小,可以直接暴力多项式乘法和取模. 然后就是常系数齐次线性递推那套理论了,戳这里 # ...

  7. sql server 小技巧(1) 导入csv数据到sql server

    1. 右击 DataBaseName,选择 Tasks->Import Data 2. 选择数据源: Flat File Source , 选择一个csv文件 Advance: 选择所有的列,改 ...

  8. service的生命周期

    Managing the Lifecycle of a Service service的生命周期,从它被创建开始,到它被销毁为止,可以有两条不同的路径: A started service 被开启的s ...

  9. sqlite 日期型 字符串转为日期型

    因为sqlite为弱引用,使用字段前将他强制转为日期型,用datetime.或者最原始的 strftime. SELECT distinct ID from testTable where datet ...

  10. centos6.5之Hadoop1.2.1完全分布式部署安装

    0. 说明 系统中首先要安装好jdk环境. 已经配置ssh免密码登录. 设置好防火墙,或者关闭防火墙. 如果集群内机器的环境完全一样,可以在一台机器上配置好,然后把master配置好的软件即hadoo ...