标签:
这场做了5题
呜呜呜---
这场老是读错题,,,还读不懂题,,,
可以滚了---
进制的转换---读好久读不懂题---
C
wtw 写的
D
读好久读不懂题---
E
F
syh发现是白薯模板题--
G
wtw 用哈希,线段树搞的--
还是不懂他怎么搞的
先用的模是1e9+7,,,wa了---
后来用了这个----998244353
就过了--
J
最开始还以为是水题----sad---
后来看了题解做的---
http://www.cnblogs.com/oyking/p/3916442.html
给出一颗n个点的树,共m个询问
每次询问a,b,c三个点,分别输出每个点 比 另外两个点近的点的个数
先考虑只有 a b 两个点的情况 ,求出一颗符合条件的子树
再考虑有 a c 两个点的情况,求出一颗符合条件的子树
然后求出这两颗子树的交集有多少个点就可以了---
题解里面的type 写得好好啊---这样可以知道这个中点是由哪一端跳上去的---
然后分四种情况来算
dep[a] > dep[b] dep[a] > dep[c]
dep[a] < dep[b] dep[a] < dep[c]
dep[a] > dep[b] dep[a] < dep[c]
dep[a] < dep[b] dep[a] > dep[c]
里面的Up(d,u) 是从一个节点u向上跳 d的距离到达的节点,,做cf的时候遇到过一次
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int INF = (1<<30)-1; 9 const int maxn = 400005; 10 const int MAX_LOG = 20; 11 12 int n,m; 13 int first[maxn],ecnt; 14 int fa[MAX_LOG][maxn],dep[maxn]; 15 int dp[maxn],vis[maxn]; 16 int sz[maxn]; 17 18 struct Edge{ 19 int u,v,next,w; 20 }; 21 22 struct node{ 23 int type,r; 24 }; 25 26 Edge e[10*maxn],ea[10*maxn]; 27 28 void init(){ 29 ecnt = 0; 30 memset(first,-1,sizeof(first)); 31 } 32 33 void Add_edge(int u,int v){ 34 e[ecnt].u = u; 35 e[ecnt].v = v; 36 e[ecnt].next = first[u]; 37 first[u] = ecnt++; 38 } 39 40 void Dfs(int p,int pre,int d){ 41 fa[0][p] = pre; 42 dep[p] = d; 43 sz[p] = 1; 44 for(int i = first[p];~i;i = e[i].next){ 45 int v = e[i].v; 46 if(v == pre) continue; 47 Dfs(v,p,d+1); 48 sz[p] += sz[v]; 49 } 50 } 51 52 void Pre(){ 53 Dfs(1,-1,0); 54 for(int k = 0;k+1 < MAX_LOG;++k){ 55 for(int v = 1;v <= n;v++){ 56 if(fa[k][v] < 0) fa[k+1][v] = -1; 57 else fa[k+1][v] = fa[k][fa[k][v]]; 58 } 59 } 60 } 61 62 int Lca(int u,int v){ 63 if(dep[u] > dep[v]) swap(u,v); 64 for(int k = MAX_LOG-1;k >= 0;--k){ 65 if(dep[v]-dep[u] & (1<<k)) 66 v = fa[k][v]; 67 } 68 if(u == v) return u; 69 for(int k = MAX_LOG-1;k >= 0;--k){ 70 if(fa[k][u] != fa[k][v]){ 71 u = fa[k][u]; 72 v = fa[k][v]; 73 } 74 } 75 return fa[0][u]; 76 } 77 78 int Up(int d,int u){ 79 for(int k = MAX_LOG-1;k >= 0;k--){ 80 if(d & (1<<k)) u = fa[k][u]; 81 } 82 return u; 83 } 84 85 node mid(int a,int b,int ab){ 86 node u; 87 int len = dep[a] + dep[b] - 2*dep[ab]; 88 if(dep[a] >= dep[b]) u = node{1,Up((len-1)/2,a)}; 89 else u = node{2,Up(len/2,b)}; 90 return u; 91 } 92 93 int solve(int a,int b,int c,int ab,int ac){ 94 node x = mid(a,b,ab); 95 node y = mid(a,c,ac); 96 int xx = x.r,yy = y.r; 97 if(x.type == 1 && y.type == 1){ 98 if(dep[xx] < dep[yy]) swap(xx,yy);//xx shi geng shen de nage 99 if(Lca(xx,yy) == yy) return sz[xx]; 100 return 0; 101 } 102 else if(x.type == 2 && y.type == 2){ 103 if(dep[xx] < dep[yy]) swap(xx,yy); 104 if(Lca(xx,yy) == yy) return n-sz[yy]; 105 else return n-sz[xx]-sz[yy]; 106 } 107 else{ 108 if(x.type == 2) swap(xx,yy);// xx shi cong a duan kai shi tiao de 109 if(Lca(xx,yy) == xx) return sz[xx]-sz[yy]; 110 else return sz[xx]; 111 } 112 } 113 114 int main(){ 115 int T; 116 scanf("%d",&T); 117 while(T--){ 118 scanf("%d",&n); 119 init(); 120 for(int i = 1;i <= n-1;i++){ 121 int u,v; 122 scanf("%d %d",&u,&v); 123 Add_edge(u,v); 124 Add_edge(v,u); 125 } 126 memset(sz,0,sizeof(sz)); 127 Pre(); 128 scanf("%d",&m); 129 for(int i = 1;i <= m;i++){ 130 int a,b,c; 131 scanf("%d %d %d",&a,&b,&c); 132 int lab = Lca(a,b); 133 int lac = Lca(a,c); 134 int lbc = Lca(b,c); 135 printf("%d %d %d\n",solve(a,b,c,lab,lac),solve(b,a,c,lab,lbc),solve(c,a,b,lac,lbc)); 136 } 137 } 138 return 0; 139 }
标签:
原文地址:http://www.cnblogs.com/wuyuewoniu/p/4918256.html