博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【纪中集训2019.3.20】铁路
阅读量:7286 次
发布时间:2019-06-30

本文共 2158 字,大约阅读时间需要 7 分钟。

题意

描述

现在有一颗树形状的双向铁路,每条边的行驶时间是\(1\)

给出\(m\)条列车行驶的路径\(s_{i}\to t_{i}\),问列车相遇的对数(无序对);

\(i和j\)号列车相遇当且仅当存在某个时刻使得\(i\)\(j\)在同一个位置,注意这个位置可能在点上,也可能在边上;

范围

$0 \le n ,m \le 10^5 $

题解

  • 相遇只有两种,同向和逆向;

  • 把边也拆成点可以解决在边上相遇的问题;

  • 考虑把每条路径按深度的大小关系划分成上行和下行(lca在上行);

  • 这样就只需要考虑上行和上行相交,上行和下行分别相交;

  • 上行和上行相加直接统计子树内出发深度相同的路径的个数;

  • 上行和下行相交树剖后变为一次函数\(x+c\)\(-x+c\)的交点个数;

  • 逆时针旋转\(45^{\circ}\) 之后做扫描线+\(BIT\)即可;

    #include
    #define pb push_back #define ll long long using namespace std;const int N=200100,M=20;int n,m,o=1,hd[N];int size[N],sn[N],tp[N],fa[N],idx,st[N],id[N],dep[N];int sz,rt[N],ls[N*M],rs[N*M],sum[N*M],cnt1,cnt2,c[N<<1];struct Edge{int v,nt;}E[N<<1];vector
    vec[N];struct data{ int x,p,typ; data(int _x=0,int _p=0,int _typ=0):x(_x),p(_p),typ(_typ){}; bool operator <(const data&A)const{return p
    '9')c=gc(); while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc(); return x; }void adde(int u,int v){ E[o]=(Edge){v,hd[u]};hd[u]=o++; E[o]=(Edge){u,hd[v]};hd[v]=o++;}void dfsA(int u,int F){ size[u]=1;sn[u]=0; dep[u]=dep[fa[u]=F]+1; for(int i=hd[u];i;i=E[i].nt){ int v=E[i].v; if(v==F)continue; dfsA(v,u); size[u]+=size[v]; if(size[v]>size[sn[u]])sn[u]=v; }}void dfsB(int u,int T){ st[++idx]=u;id[u]=idx;tp[u]=T; if(sn[u])dfsB(sn[u],T); for(int i=hd[u];i;i=E[i].nt){ int v=E[i].v; if(v==fa[u]||v==sn[u])continue; dfsB(v,v); }} int lca(int u,int v){ int tu=tp[u],tv=tp[v]; while(tu!=tv){ if(dep[tu]
    >1; if(x<=mid)update(ls[k],l,mid,x,y); else update(rs[k],mid+1,r,x,y);}void merge(int&x,int&y){ if(!x||!y){x=x+y;return;} if(!ls[x]&&!rs[x]){ sum[x]=sum[x]+sum[y]; return ; } merge(ls[x],ls[y]); merge(rs[x],rs[y]); sum[x]=sum[ls[x]]+sum[rs[x]];}int query(int k,int l,int r,int x){ --sum[k]; if(l==r)return sum[k]; int mid=l+r>>1; if(x<=mid)return query(ls[k],l,mid,x); else return query(rs[k],mid+1,r,x);}void dfsC(int u){ for(int i=hd[u];i;i=E[i].nt){ int v=E[i].v; if(v==fa[u])continue; dfsC(v); merge(rt[u],rt[v]); } for(int i=0;i

转载于:https://www.cnblogs.com/Paul-Guderian/p/10574113.html

你可能感兴趣的文章
linux学习第4天(自习)
查看>>
持续更新:Centos常用方便的命令与技巧集合
查看>>
ubuntu 终端vi和gedit中文乱码解决方案
查看>>
Linux下无连接的套接字通信C实现
查看>>
ipv6
查看>>
CCNA入门---交换机端口安全的四种行为
查看>>
获取当前时间的时分秒
查看>>
mysql5.6源码拷贝不编译安装
查看>>
centos7 安装iftop
查看>>
CISCO之BGP配置
查看>>
python ConfigParser 模块
查看>>
如何通过Word 2010发布文章到博客
查看>>
JVM监控和查看
查看>>
$.ajax与$.post,$.get的区别
查看>>
Java开发者易犯错误Top10
查看>>
Xcode快捷键整理(陆续添加中)
查看>>
分布式系统的事务处理
查看>>
VC 双缓存技术+滚动条
查看>>
strtol详解
查看>>
mysql部分参数注解
查看>>