hihocoder1167 Advanced Theoretical Computer Science[树剖][LCA]
来源:互联网 发布:雇一次网络水军多钱 编辑:程序博客网 时间:2024/06/11 03:35
Advanced Theoretical Computer Science
Time Limit: 20000MS Memory Limit: 262144KB 64bit IO Format: %lld & %llu
Submit
Status
Description
Yuuka is learning advanced theoretical computer science these days.But she cannot understand it. So she decided to hang out to relax.
Outside the door there is a tree of n nodes. She found there are P fairies on the tree. The fairies are very nervous, so each fairy only shows on a particular route on the tree. To be more specific, the i-th fairy will show on the path between nodes ai and bi.
Two fairies are friends if there route have some (no less than one) points in common.
Yuuka wants to know that how many pairs of fairies a,b (a!=b) are friends. Note that a,b and b,a are considered to be the same.
Input
The first line with two integers n and P (1 <= n, P <= 100000), meaning the size of the tree and the number of fairies. The nodes in the tree are numbered from 1 to n.
Then following n-1 lines with two integers a and b on each line, meaning there is an edge between a and b (a!=b).
Then following P lines, each line with two integers ai and bi, meaning the i-th fairy will show on the path from ai to bi. (ai!=bi)
Output
One line with an integer representing the answer.
Sample Input
6 3
1 2
2 3
2 4
4 5
4 6
1 3
1 5
5 6
Sample Output
2
Source
hihoCoder Challenge 11
Problem descriptions:
System Crawler 2016-10-18
Initialization.
Discuss
题意:给定树和链,求有多少对链有交点;
分析:可以分析得,两条链相交当且仅当LCA较深的链的LCA在另一条链上时,所以很容易想到用树剖搞定,可以对LCA的深度进行排序,然后询问一次改一个点,询问的是链上的点数,改变的是线段树上链上的点数(改链容易出问题);
第一次写和std对拍了很久都没有找出问题,但WA了,应该是某些特殊数据,复习的时候再写一次。
WA了的,球大神查错:
#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<cstring>using namespace std;const int maxn=1e5+5;int n,m,sta,fin,idx,cnt;int tov[maxn*2],fr[maxn],des[maxn*2],fa[maxn],dep[maxn],siz[maxn],sig[maxn];int tiilca[maxn*2],f[maxn*4][20],top[maxn],tii[maxn],son[maxn];struct node{ int lef,rig,sig; }a[maxn*8];struct node2{ int sta,fin,lca;}b[maxn];bool cmp(node2 x,node2 y){ return dep[x.lca]>dep[y.lca];}void addedge(int cur){ scanf("%d %d",&sta,&fin); tov[2*cur-1]=fr[sta];fr[sta]=2*cur-1;des[2*cur-1]=fin; tov[2*cur]=fr[fin];fr[fin]=2*cur;des[2*cur]=sta;}void dfs(int u,int fro,int ste){ fa[u]=fro;dep[u]=ste;siz[u]=1; tiilca[++idx]=u;sig[u]=idx;f[idx][0]=idx; for(int i=fr[u];i;i=tov[i]) if(des[i]!=fro){ dfs(des[i],u,ste+1); tiilca[++idx]=u; f[idx][0]=sig[u]; siz[u]+=siz[des[i]]; if(siz[des[i]]>siz[son[u]]) son[u]=des[i]; }}void dfs2(int u,int fro,int t){ top[u]=t;tii[u]=++cnt; if(son[u])dfs2(son[u],u,t); for(int i=fr[u];i;i=tov[i]) if(des[i]!=fro&&des[i]!=son[u]) dfs2(des[i],u,des[i]);}void bz(){ for(int i=1;i<=17;i++)for(int j=1;j<=2*n-1;j++) f[j][i]=min(f[j][i-1],f[j+(1<<(i-1))][i-1]);}void build(int u,int lef,int rig){ a[u].lef=lef;a[u].rig=rig; int mid=(lef+rig)>>1; if(lef!=rig) build(2*u,lef,mid),build(2*u+1,mid+1,rig);}int lookfor(int lef,int rig){ if(sig[lef]>sig[rig])swap(lef,rig); int tmp=floor(log(sig[rig]-sig[lef]+1)/log(2)); return tiilca[min(f[sig[lef]][tmp],f[sig[rig]+1-(1<<tmp)][tmp])];}void update(int u,int dot){ a[u].sig++; if(a[u].lef==a[u].rig&&a[u].rig==dot)return; int mid=(a[u].lef+a[u].rig)>>1; if(dot<=mid)update(2*u,dot); else update(2*u+1,dot);}int query(int u,int lef,int rig){ if(a[u].lef==lef&&a[u].rig==rig)return a[u].sig; else{ int mid=(a[u].lef+a[u].rig)>>1; if(rig<=mid)return query(2*u,lef,rig); else if(lef>mid)return query(2*u+1,lef,rig); else return query(2*u,lef,mid)+query(2*u+1,mid+1,rig); }}int queryctrl(int u){ sta=b[u].sta;fin=b[u].fin; int ret=0; int fa1=top[sta],fa2=top[fin]; while(fa1!=fa2){ if(dep[fa1]<dep[fa2]){ swap(sta,fin);swap(fa1,fa2); } ret+=query(1,tii[fa1],tii[sta]); sta=fa[fa1];fa1=top[sta]; } if(sta==fin)return ret; if(tii[sta]>tii[fin])swap(sta,fin); ret+=query(1,tii[sta],tii[fin]); return ret;}void work(){ int ans=0; for(int i=1;i<=m;i++) scanf("%d %d",&b[i].sta,&b[i].fin); for(int i=1;i<=m;i++) b[i].lca=lookfor(b[i].sta,b[i].fin); sort(b+1,b+m+1,cmp); for(int i=1;i<=m;i++){ ans+=queryctrl(i); update(1,tii[b[i].lca]); } printf("%d",ans);}void init(){ memset(f,127,sizeof(f)); scanf("%d %d",&n,&m); for(int i=1;i<n;i++)addedge(i); dfs(1,1,0); dfs2(1,1,1); bz();build(1,1,n);}int main(){ freopen("hihocoder1167.in","r",stdin); freopen("hihocoder1167.out","w",stdout); init(); work(); return 0;}
std:
#include <cstdio>#include <iostream>#include <cstring>using namespace std;typedef long long LL;#define MAXN 100010struct Edge { int to, next;} edge[MAXN << 1];struct Node { int to, next, num;} Query[MAXN << 1];struct node { int u, v, lca;} input[MAXN];int totEdge, totQuery, n, m;int headEdge[MAXN], headQuery[MAXN];int ancestor[MAXN], father[MAXN], LCAnum[MAXN], sum[MAXN];bool vis[MAXN];void addEdge(int from, int to) { edge[totEdge].to = to; edge[totEdge].next = headEdge[from]; headEdge[from] = totEdge++;}void addQuery(int from, int to, int x) { Query[totQuery].to = to; Query[totQuery].num = x; Query[totQuery].next = headQuery[from]; headQuery[from] = totQuery++;}void init() { memset(headEdge, -1, sizeof(headEdge)); memset(headQuery, -1, sizeof(headQuery)); memset(father, -1, sizeof(father)); memset(vis, false, sizeof(vis)); memset(sum, 0, sizeof(sum)); memset(LCAnum, 0, sizeof(LCAnum)); totEdge = totQuery = 0;}int find_set(int x) { if(x == father[x]) return x; else return father[x] = find_set(father[x]);}void union_set(int x, int y) { x = find_set(x); y = find_set(y); if(x != y) father[y] = x;}void Tarjan(int u) { father[u] = u; for(int i = headEdge[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(father[v] != -1) continue; Tarjan(v); union_set(u, v); } for(int i = headQuery[u]; i != -1; i = Query[i].next) { int v = Query[i].to; if(father[v] == -1) continue; input[Query[i].num].lca = find_set(v); }}void DFS(int u, int pre) { vis[u] = 1; sum[u] = sum[pre] + LCAnum[u]; for(int i = headEdge[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(vis[v]) continue; DFS(v, u); }}int main() { freopen("hihocoder1167.in","r",stdin); freopen("hihocoder11671.out","w",stdout); init(); scanf("%d%d", &n, &m); for(int i = 0; i < n - 1; i++) { int a, b; scanf("%d%d", &a, &b); addEdge(a, b); addEdge(b, a); } for(int i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); input[i].u = a, input[i].v = b; addQuery(a, b, i); addQuery(b, a, i); } Tarjan(1); for(int i = 0; i < m; i++) LCAnum[input[i].lca]++; DFS(1, 0); LL ans = 0; for(int i = 0; i < m; i++) { ans += (sum[input[i].u] + sum[input[i].v] - 2 * sum[input[i].lca]); } for(int i = 1; i <= n; i++) { ans += (LL)LCAnum[i] * (LCAnum[i] - 1) / 2; } printf("%lld\n", ans); return 0;}
- hihocoder1167 Advanced Theoretical Computer Science[树剖][LCA]
- hiho 1167Advanced Theoretical Computer Science LCA
- 倍增法求LCA -- HihoCoder 1167 Advanced Theoretical Computer Science
- Theoretical Computer Science 录用文章一篇
- 《Great Theoretical Ideas In Computer Science》学习笔记
- 关于理论计算科学(Theoretical computer science)
- Software Engineering 3: Domains, Requirements, and Software Design (Texts in Theoretical Computer Science. An EATCS Series)
- Computer Science
- computer science
- Computer and Computer Science
- Synchronization (computer science)
- Mathematics for Computer Science
- why computer science
- C ++ Namespace (computer science)
- Computer Science Conference rankings
- Computer Science Conference Rankings
- Computer Science Conference Rankings
- Barrier (computer science)
- java.lang.NullPointerException: Attempt to write to field 'int android.support.v7.widget.RecyclerVie
- Python入门学习笔记1(变量、运算符、数据类型I)
- MVP、MVP、 MVVM 设计模式详解
- iOS调用系统相册和相机选择图片
- 1133. SPAM
- hihocoder1167 Advanced Theoretical Computer Science[树剖][LCA]
- Mybatis中的<association>用法
- 文本域字数统计
- ssl_write直接程序挂掉
- Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister报错解决办法
- poj 2440 DNA (dp|递推|找规律|矩阵乘法)
- Leetcode 413. Arithmetic Slices 所有等差序列 解题报告
- NOIP2014 联合权值
- Java之next()与nextline区别