【NOIP2017提高A组模拟10.5】Ping
来源:互联网 发布:美工接单群 编辑:程序博客网 时间:2024/05/23 19:03
Description
Input
Output
Sample Input
5 4
2 1
5 3
3 1
4 3
2
2 4
3 2
Sample Output
1
2
Data Constraint
题解
这是一道比较玄学的题目
首先我们看一下在一条链怎么做,我们可以先把右端点排一下序,从左到右扫一遍,每次遇到一个左端点就把它加入到队列里面,遇到一个右端点就把整个序列清空,并且答案+1,这样很显然是对的,因为我如果再往右就覆盖不到第一个了,如果不那么右后面的一些可能又覆盖不到(那不是亏了)
然后这个结论可以拓展到树上面,可以把所有询问的lca的dfs序倒序排一下序,然后再按照顺序查找,每一次我们看一下那个询问的路径上面有没有已经删掉的点,否则我们就删掉根节点,证明和上面的都差不多
具体实现的话可以用线段树
贴代码
#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#define fo(i,a,b) for(i=a;i<=b;i++)#define fo1(i,b,a) for(i=b;i>=a;i--)using namespace std;const int maxn=2e5+5;struct P{ int x,y,z,p;}a[maxn*2];int fi[maxn],ne[maxn*2],dui[maxn*2],qc[maxn],dfn[maxn],sum[maxn],de[maxn],size[maxn],ans[maxn];int tree[maxn*3];bool bz[maxn];int ff[maxn][19];int i,j,k,l,n,m,x,y,z,now,p,tot,cc;void add(int x,int y){ if (fi[x]==0) fi[x]=++now; else ne[qc[x]]=++now; qc[x]=now; dui[now]=y;}void dfs(int x){ bz[x]=true; int i=fi[x]; dfn[x]=++p; size[x]=1; while (i){ if (bz[dui[i]]==true){ i=ne[i]; continue; } ff[dui[i]][0]=x; de[dui[i]]=de[x]+1; dfs(dui[i]); size[x]+=size[dui[i]]; }}void ge_ff(){ fo(j,1,17) fo(i,1,n) ff[i][j]=ff[ff[i][j-1]][j-1];}int m1a(int x,int y){ if (de[x]<de[y]){ z=x; x=y; y=z; } int i; fo1(i,16,0)if (de[x]-(1<<i)>=de[y]){ x=ff[x][i]; } fo1(i,16,0)if (ff[x][i]!=ff[y][i]){ x=ff[x][i]; y=ff[y][i]; } if (x!=y) x=ff[x][0]; return x;}int cmp(P x,P y){ return x.p>y.p;}void change(int v,int l,int r,int x){ if (l==r){ tree[v]+=z; } else{ int mid=(l+r)/2; if (x<=mid) change(v*2,l,mid,x); else change(v*2+1,mid+1,r,x); tree[v]=tree[v*2]+tree[v*2+1]; }}void find(int v,int l,int r,int x,int y){ if (l==x && r==y){ tot=tot+z*tree[v]; } else{ int mid=(l+r)/2; if (y<=mid) find(v*2,l,mid,x,y); else if (x>mid) find(v*2+1,mid+1,r,x,y); else{ find(v*2,l,mid,x,mid); find(v*2+1,mid+1,r,mid+1,y); } }}int main(){ freopen("ping.in","r",stdin); freopen("ping.out","w",stdout); scanf("%d%d",&n,&m); fo(i,1,n-1){ scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(1); ge_ff(); scanf("%d",&m); fo(i,1,m){ scanf("%d%d",&x,&y); a[i].x=dfn[x]; a[i].y=dfn[y]; a[i].z=m1a(x,y); a[i].p=dfn[a[i].z]; } sort(a+1,a+m+1,cmp); fo(i,1,m){ tot=0; z=1; find(1,1,n+1,1,a[i].x); find(1,1,n+1,1,a[i].y); z=-1; find(1,1,n+1,1,a[i].p); if (!tot){ z=1; change(1,1,n+1,a[i].p); z=-1; change(1,1,n+1,a[i].p+size[a[i].z]); ans[++cc]=a[i].z; } } printf("%d\n",cc); fo(i,1,cc) printf("%d ",ans[i]); return 0;}
阅读全文
0 0
- 【NOIP2017提高A组模拟10.5】Ping
- 【NOIP2017提高A组模拟10.5】Ping
- 【NOIP2017提高A组模拟10.5】Ping
- jzoj5394 【NOIP2017提高A组模拟10.5】Ping
- 【JZOJ 5394】【NOIP2017提高A组模拟10.5】Ping
- [JZOJ5394]【NOIP2017提高A组模拟10.5】Ping
- JZOJ5394. 【NOIP2017提高A组模拟10.5】Ping 树上差分 树状数组
- JZOJ 5392. 【NOIP2017提高A组模拟10.5】Lucky Transformation
- 【NOIP2017提高A组模拟10.5】Snake vs Block
- A【NOIP2017提高组模拟12.18】
- 【JZOJ4928】【NOIP2017提高组模拟12.18】A
- 【NOIP2017提高组模拟12.18】A
- 【JZOJ4928】【NOIP2017提高组模拟12.18】A
- 【NOIP2017提高A组模拟7.7】图
- 【NOIP2017提高A组模拟7.13】abcd
- 区间【NOIP2017提高A组模拟7.10】
- 【NOIP2017提高A组模拟8.22】密码
- 【NOIP2017提高A组模拟8.23】密码
- 白话空间统计之二十五:空间权重矩阵(四)R语言中的空间权重矩阵(4):K临近
- 【实践】通用文件系统的quota时间
- 求a的b次方,不用考虑大数问题,不使用库函数
- String类中lastIndexOf()与indexOf()方法的区别
- python ctrl+c 退出while True:
- 【NOIP2017提高A组模拟10.5】Ping
- Java异常:一个线程运行时发生异常会怎样?
- Rust: join,与concat
- Tkinter——在text中插入图片
- [DP 决策单调 分治]Codeforces 868F .Yet Another Minimization Problem
- 《算-入》第一章
- 程序猿必备资源清单(安卓居多)
- springmvc学习笔记(5)-入门程序小结
- 卷积神经网络