原题传送门

看到这种树上统计点对个数的题一般是线段树合并,这题也不出意外

先对这棵树进行树剖,对于每次普及语言,在\(x,y\)两点的线段树上的\(x,y\)两位置打\(+1\)标记,在点\(fa[lca(x,y)]\)的线段树上\(x,y\)两位置打\(-2\)标记

线段树中该维护三个东西:

1.dfs序最小的\(lp\)

2.dfs序最大的\(rp\)

3.线段树中所有被打标机的点到根节点路径的并的节点个数\(sum\)

我们进行搜索并从下向上的进行线段树合并,对于每个节点,对答案的贡献就是该节点线段树的根节点的\(sum-dep[lca(lp,rp)]+1-1\)(珂以画图理解一下)

交上去,发现wa了,因为每条路径的贡献被我们算了\(2\)次,所以除以2即可

#include <bits/stdc++.h>
#define N 100005
#define ll long long
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register ll x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
int n,m;
ll ans;
struct edge{
int to,next;
}e[N<<1];
int head[N],cnt=0;
inline void add(register int u,register int v)
{
e[++cnt]=(edge){v,head[u]};
head[u]=cnt;
}
int size[N],fa[N],son[N],dep[N],top[N],dfn[N],tim,idfn[N];
inline void dfs1(register int x)
{
size[x]=1;
for(register int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v==fa[x])
continue;
dep[v]=dep[x]+1;
fa[v]=x;
dfs1(v);
size[x]+=size[v];
if(size[v]>size[son[x]])
son[x]=v;
}
}
inline void dfs2(register int x,register int t)
{
dfn[x]=++tim;
idfn[tim]=x;
top[x]=t;
if(son[x])
dfs2(son[x],t);
for(register int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa[x]&&v!=son[x])
dfs2(v,v);
}
}
inline int getlca(register int x,register int y)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[fx]<dep[fy])
{
x^=y^=x^=y;
fx^=fy^=fx^=fy;
}
x=fa[fx];
fx=top[x];
}
return dep[x]<dep[y]?x:y;
}
int root[N],tot;
struct node{
int ls,rs,cnt,lp,rp,sum;
}tr[N*60];
inline void pushup(register int x)
{
tr[x].lp=tr[tr[x].ls].lp?tr[tr[x].ls].lp:tr[tr[x].rs].lp;
tr[x].rp=tr[tr[x].rs].rp?tr[tr[x].rs].rp:tr[tr[x].ls].rp;
tr[x].sum=tr[tr[x].ls].sum+tr[tr[x].rs].sum;
if(tr[tr[x].ls].rp&&tr[tr[x].rs].lp)
tr[x].sum-=dep[getlca(tr[tr[x].ls].rp,tr[tr[x].rs].lp)];
}
inline void modify(register int &x,register int l,register int r,register int pos,register int val)
{
if(!x)
x=++tot;
if(l==r)
{
tr[x].cnt+=val;
if(tr[x].cnt)
tr[x].lp=tr[x].rp=pos,tr[x].sum=dep[pos];
else
tr[x].lp=tr[x].rp=tr[x].sum=0;
return;
}
int mid=l+r>>1;
if(dfn[pos]<=mid)
modify(tr[x].ls,l,mid,pos,val);
else
modify(tr[x].rs,mid+1,r,pos,val);
pushup(x);
}
inline void merge(register int &a,register int b,register int l,register int r)
{
if(!a||!b)
{
a=a+b;
return;
}
if(l==r)
{
tr[a].cnt+=tr[b].cnt;
if(tr[a].cnt)
tr[a].lp=tr[a].rp=idfn[l],tr[a].sum=dep[idfn[l]];
else
tr[a].lp=tr[a].rp=tr[a].sum=0;
return;
}
int mid=l+r>>1;
merge(tr[a].ls,tr[b].ls,l,mid);
merge(tr[a].rs,tr[b].rs,mid+1,r);
pushup(a);
}
inline void dfs(register int x)
{
for(register int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v==fa[x])
continue;
dfs(v);
merge(root[x],root[v],1,tim);
}
if(tr[root[x]].lp&&tr[root[x]].rp)
ans+=tr[root[x]].sum-dep[getlca(tr[root[x]].lp,tr[root[x]].rp)];
}
int main()
{
n=read(),m=read();
for(register int i=1;i<n;++i)
{
int u=read(),v=read();
add(u,v),add(v,u);
}
dfs1(1);
dfs2(1,0);
for(register int i=1;i<=m;++i)
{
int x=read(),y=read();
int lca=getlca(x,y);
modify(root[x],1,tim,x,1);
modify(root[x],1,tim,y,1);
modify(root[y],1,tim,x,1);
modify(root[y],1,tim,y,1);
if(lca>1)
{
modify(root[fa[lca]],1,tim,x,-2);
modify(root[fa[lca]],1,tim,y,-2);
}
}
dfs(1);
write(ans>>1);
return 0;
}

【题解】Luogu P5327 [ZJOI2019]语言的更多相关文章

  1. Luogu P5327 [ZJOI2019]语言

    ZJOI2019Day2的温暖题,然后考场上只会大常数的\(O(n\log^3 n)\),就懒得写拿了60pts走人 首先我们简化题意,容易发现每个点能到达的点形成了一个联通块,我们只需要统计出这个联 ...

  2. 题解 P5327 [ZJOI2019]语言

    P5327 [ZJOI2019]语言 解题思路 暴力 首先讲一下我垃圾的 40pts 的暴力(其他 dalao 都是 60pts 起步): 当然评测机快的话(比如 LOJ 的),可以卡过 3,4 个点 ...

  3. P5327 [ZJOI2019]语言

    一边写草稿一边做题吧.要看题解的往下翻,或者是旁边的导航跳一下. 草稿 因为可以开展贸易活动的条件是存在一种通用语 \(L\) 满足 \(u_i\) 到 \(v_i\) 的最短路径上都会 \(L\) ...

  4. [题解] Luogu P5446 [THUPC2018]绿绿和串串

    [题解] Luogu P5446 [THUPC2018]绿绿和串串 ·题目大意 定义一个翻转操作\(f(S_n)\),表示对于一个字符串\(S_n\), 有\(f(S)= \{S_1,S_2,..., ...

  5. 【题解】Luogu P5279 [ZJOI2019]麻将

    原题传送门 希望这题不会让你对麻将的热爱消失殆尽 我们珂以统计每种牌出现的次数,不需要统计是第几张牌 判一副牌能不能和,类似这道题 对于这题: 设\(f[i][j][k][0/1]\)表示前\(i\) ...

  6. 【题解】Luogu P5328 [ZJOI2019]浙江省选

    原题传送门 看起来挺妙实际很暴力的一题 已知每个选手的分数都是平面上的直线 题目实际就是让我们求每条直线在整点处最大是第几大 我们考虑先对所有的直线进行半平面交(因为\(a_i\)都是正整数,所以比普 ...

  7. 题解 [ZJOI2019]语言

    题目传送门 题目大意 给出一个 \(n\) 个点的树,现在有 \(m\) 次操作,每次可以选择一个链 \(s,t\),,然后这条链上每个点都会增加一个相同属性,问对于每一个点有与它相同属性的有多少个点 ...

  8. 题解 Luogu P2499: [SDOI2012]象棋

    关于这道题, 我们可以发现移动顺序不会改变答案, 具体来说, 我们有以下引理成立: 对于一个移动过程中的任意一个移动, 若其到达的位置上有一个棋子, 则该方案要么不能将所有棋子移动到最终位置, 要么可 ...

  9. Luogu P5279 [ZJOI2019]麻将

    ZJOI2019神题,间接送我退役的神题233 考场上由于T2写挂去写爆搜的时候已经没多少时间了,所以就写挂了233 这里不多废话直接开始讲正解吧,我们把算法分成两部分 1.建一个"胡牌自动 ...

随机推荐

  1. maven 学习---Maven本地资源库

    Maven的本地资源库是用来存储所有项目的依赖关系(插件jar和其他文件,这些文件被Maven下载)到本地文件夹. 很简单,当你建立一个Maven项目,所有相关文件将被存储在你的Maven本地仓库. ...

  2. Quality Center安装步骤

     测试管理工具 u 安装条件: Quality Center:QC9中文版 数据库:Oracle10 g 操作系统:Windows XP u 安装步骤: 1. 点击setup.exe,出现如下界面,点 ...

  3. CentOS6.7编译安装mysql5.5(详解编译选项)

    注意!  mysql5.5之前一般都是用make编译 mysql5.5 -5.6 一般都是用cmake编译 cmake : 跨平台编译器, mysql官方提供的rpm包 mysql-client :提 ...

  4. 团队第五次作业:alpha2成绩汇总

    一.作业题目 团队第五次作业:alpha2发布 二.作业评分标准 博客评分规则(总分100)博客要求 给出开头和团队成员列表(10') 给出发布地址以及安装手册(20') 给出测试报告(40') 给出 ...

  5. C# HttpClient Post 参数同时上传文件 上传图片 调用接口

    // 调用接口上传文件 using (var client = new HttpClient()) { using (var multipartFormDataContent = new Multip ...

  6. django 自定义分页,网址存储缓存,CBV

    1. 通过切片控制分页 自定义分页: from django.shortcuts import render # Create your views here. from app01.models i ...

  7. 冬令营DAY3 T1 Matrix

    题目描述 Description    生活中,我们常常用 233 表示情感.实际上,我们也会说 2333,23333,等等. 于是问题来了: 定义一种矩阵,称为 233 矩阵.矩阵的第一行依次是 2 ...

  8. RabbitMQ消息幂等性问题

    文章目录 1. 什么是幂等性?1.1 消息队列的幂等性1.2 模拟重试机制1.2.1 生产者代码1.2.2 消费者代码1.2.3 消费者 application.yml 配置2. 如何保证消息幂等性, ...

  9. 生成随机文件名JS

    export default function (length) { const data = ["0", "1", "2", " ...

  10. First Chance Exception是什么?

    是否调试过应用程序并在输出窗口中看到有关“First Chance”异常的消息?有没有想过: 什么是First Chance Exception? 第一次机会异常是否意味着我的代码中存在问题? 在调试 ...