传送门

话说开始上文化课之后写题时间好少啊。

这道题将一个人的跑步路线拆成s->lca,lca->t,然后对于第一段上坡路径要经过的点,当前这个人能对它产生贡献当且仅当dep[s]-dep[i]==w[i],对于第二段路径同理能产生贡献当且仅当dep[t]-dep[i]==dis(s,t)-w[i],同时需要看lca有没有被算重,这几个东西一看就可以差分,但差分不仅不好想也不好写,我就用数据结构来代替啦。

其实就是树链剖分+动态开点。

代码:

#include<bits/stdc++.h>
#define N 300005
using namespace std;
int n,m;
int hson[N],num[N],ans[N],first[N],top[N],dep[N],fa[N],siz[N],dfn=0,tot=0,cnt=0,rt[N*3];
struct Node{int l,r,sum;}T[N*30];
struct node{int v,next;}e[N<<1];
int s[N],t[N],w[N],lca[N];
inline void add(int u,int v){e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt;}
inline int read(){
    int ret=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();
    return ret;
}
inline void dfs1(int p){
    siz[p]=1,hson[p]=0;
    for(int i=first[p];i;i=e[i].next){
        int v=e[i].v;
        if(v==fa[p])continue;
        fa[v]=p,dep[v]=dep[p]+1,dfs1(v),siz[p]+=siz[v];
        if(siz[v]>siz[hson[p]])hson[p]=v;
    }
}
inline void dfs2(int p,int tp){
    top[p]=tp,num[p]=++dfn;
    if(hson[p])dfs2(hson[p],tp);
    for(int i=first[p];i;i=e[i].next){
        int v=e[i].v;
        if(v!=hson[p]&&v!=fa[p])dfs2(v,v);
    }
}
inline void update(int&p,int l,int r,int k,int v){
    if(!p)p=++tot,T[p].l=T[p].r=T[p].sum=0;
    T[p].sum+=v;
    if(l==r)return;
    int mid=l+r>>1;
    if(k<=mid)update(T[p].l,l,mid,k,v);
    else update(T[p].r,mid+1,r,k,v);
}
inline int query(int p,int l,int r,int ql,int qr){
    if(!p)return 0;
    if(ql<=l&&r<=qr)return T[p].sum;
    int mid=l+r>>1;
    if(qr<=mid)return query(T[p].l,l,mid,ql,qr);
    if(ql>mid)return query(T[p].r,mid+1,r,ql,qr);
    return query(T[p].l,l,mid,ql,mid)+query(T[p].r,mid+1,r,mid+1,qr);
}
inline int LCA(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        x=fa[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<n;++i){
        int u=read(),v=read();
        add(u,v),add(v,u);
    }
    for(int i=1;i<=n;++i)w[i]=read();
    dfs1(1),dfs2(1,1);
    for(int i=1;i<=m;++i){
        s[i]=read(),t[i]=read();
        lca[i]=LCA(s[i],t[i]);
        if(dep[s[i]]-dep[lca[i]]==w[lca[i]])--ans[lca[i]];
        update(rt[dep[s[i]]],1,n,num[s[i]],1);
        if(fa[lca[i]])update(rt[dep[s[i]]],1,n,num[fa[lca[i]]],-1);
    }
    for(int i=1;i<=n;++i)ans[i]+=query(rt[w[i]+dep[i]],1,n,num[i],num[i]+siz[i]-1);
    memset(rt,0,sizeof(rt)),tot=0;
    for(int i=1;i<=m;++i){
        update(rt[n*2+dep[s[i]]-2*dep[lca[i]]],1,n,num[t[i]],1);
        if(fa[lca[i]])update(rt[n*2+dep[s[i]]-2*dep[lca[i]]],1,n,num[fa[lca[i]]],-1);
    }
    for(int i=1;i<=n;++i)ans[i]+=query(rt[w[i]-dep[i]+n*2],1,n,num[i],num[i]+siz[i]-1);
    for(int i=1;i<=n;++i)cout<<ans[i]<<' ';
    return 0;
}

2018.08.09 bzoj4719: [Noip2016]天天爱跑步(树链剖分)的更多相关文章

  1. BZOJ 4719 [Noip2016]天天爱跑步 ——树链剖分

    一直以为自己当时是TLE了,但是再看发现居然WA? 然后把数组扩大一倍,就A掉了.QaQ 没什么好说的.一段路径分成两段考虑,上升的一段深度+时间是定值,下降的一段深度-时间是定值,然后打标记统计即可 ...

  2. NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分

    原文链接https://www.cnblogs.com/zhouzhendong/p/9275606.html 题目传送门 - 洛谷P1600 题目传送门 - LOJ#2359 题目传送门 - Vij ...

  3. BZOJ4719 [Noip2016]天天爱跑步

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  4. BZOJ4719 NOIP2016天天爱跑步(线段树合并)

    线段树合并的话这个noip最难题就是个裸题了. 注意merge最后return x,以及如果需要区间查询的话这里还需要up,无数次死于这里. #include<iostream> #inc ...

  5. 2018.09.16 bzoj3626: [LNOI2014]LCA(树链剖分)

    传送门 树链剖分好题. 对于每个点维护一个值vi" role="presentation" style="position: relative;"&g ...

  6. 2018.10.30 NOIP训练 【模板】树链剖分(换根树剖)

    传送门 纯粹是为了熟悉板子. 然后发现自己手生了足足写了差不多25min而且输出的时候因为没开long longWA了三次还不知所云 代码

  7. [NOIp2016]天天爱跑步 线段树合并

    [NOIp2016]天天爱跑步 LG传送门 作为一道被毒瘤出题人们玩坏了的NOIp经典题,我们先不看毒瘤的"动态爱跑步"和"天天爱仙人掌",回归一下本来的味道. ...

  8. [Noip2016]天天爱跑步 LCA+DFS

    [Noip2016]天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要玩家每天按时上线,完成打卡任 ...

  9. 【LG1600】[NOIP2016]天天爱跑步

    [LG1600][NOIP2016]天天爱跑步 题面 洛谷 题解 考虑一条路径\(S\rightarrow T\)是如何给一个观测点\(x\)造成贡献的, 一种是从\(x\)的子树内出来,另外一种是从 ...

随机推荐

  1. springVC + logback

    为什么用logback,而不是log4j? springmvc log只输出到console,不输出到文件 Spring MVC集成slf4j-logback springMVC如何配置logback ...

  2. as2 fla 关于影片在时间轴的问题

    多帧上面放着没实例名而且里面内容一致的影片,主要一开始读取了,那么跳帧的时候.会自动获取当前帧上的相同内容的影片. 但如果内容不一致的影片,那么在跳帧后,不会获取当前的影片,旧的影片也无法获取.只在当 ...

  3. cv::circle《转》

    void circle(CV_IN_OUT Mat& img, Point center, int radius, const Scalar& color, int thickness ...

  4. Java并发知识(1)

    1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含了不同的类和 ...

  5. 锋利的BFC

    在初学前端的时候,我们会经常碰到各种各样的布局问题,尤其当使用浮动的时候,然而学习了BFC之后,其中的一些怪异现象,也因此成为理所当然,会有一种拨开云雾的快感. 下面简单介绍下BFC,究竟什么是BFC ...

  6. UGUI 实例预制对象位置不对

    public static Object Instantiate(Object original, Transform parent, bool instantiateInWorldSpace); / ...

  7. 刚刚安装完nginx,服务启动,通过浏览器无法访问的问题

    查看Linux服务是否启动. ps -ef | grep nginx 解决办法:1,添加 80 段端口配置 firewall-cmd --zone=public --add-port=80/tcp - ...

  8. layer 弹出层 不居中

    layer弹出层不居中解决方案 代码头中加入以下代码即可 <!doctype html>

  9. pyplot绘图区域

    pyplot绘图区域 Matplotlib图像组成 matplotlib中,整个图像为一个Figure对象,与用户交互的整个窗口 Figure对象中包含一个或多个Axes(ax)子对象,每个ax子对象 ...

  10. SQL获取分组后取某字段最大一条记录(求每个类别中最大的值的列表)

    获取分组后取某字段最大一条记录 方法一:(效率最高) select * from test as a where typeindex = (select max(b.typeindex) from t ...