JZOJ 5782. 【NOIP提高A组模拟2018.8.8】 城市猎人

有n个城市,标号为1到n,修建道路花费m天,第i天时,若gcd(a,b)=m-i+1,则标号为a的城市和标号为b的城市会建好一条直接相连的道路,有多次询问,每次询问某两座城市最早什么时候能连通。

对于40%的数据,n≤ 1000,q<=100000

对于100%的数据,1 ≤ n,q≤ 100000,1<=m<=q

如果想到了kruskal重构树,那应该是学傻了 像我一样

直接并查集按秩合并就行了,边权就是合并时的时间,查询就暴力爬链,查询两点之间的最大边权

硬核优化

 1 %:pragma GCC optimize(2)
 2 %:pragma GCC optimize(3)
 3 %:pragma GCC optimize("Ofast")
 4 %:pragma GCC optimize("inline")
 5 %:pragma GCC optimize("-fgcse")
 6 %:pragma GCC optimize("-fgcse-lm")
 7 %:pragma GCC optimize("-fipa-sra")
 8 %:pragma GCC optimize("-ftree-pre")
 9 %:pragma GCC optimize("-ftree-vrp")
10 %:pragma GCC optimize("-fpeephole2")
11 %:pragma GCC optimize("-ffast-math")
12 %:pragma GCC optimize("-fsched-spec")
13 %:pragma GCC optimize("unroll-loops")
14 %:pragma GCC optimize("-falign-jumps")
15 %:pragma GCC optimize("-falign-loops")
16 %:pragma GCC optimize("-falign-labels")
17 %:pragma GCC optimize("-fdevirtualize")
18 %:pragma GCC optimize("-fcaller-saves")
19 %:pragma GCC optimize("-fcrossjumping")
20 %:pragma GCC optimize("-fthread-jumps")
21 %:pragma GCC optimize("-funroll-loops")
22 %:pragma GCC optimize("-fwhole-program")
23 %:pragma GCC optimize("-freorder-blocks")
24 %:pragma GCC optimize("-fschedule-insns")
25 %:pragma GCC optimize("inline-functions")
26 %:pragma GCC optimize("-ftree-tail-merge")
27 %:pragma GCC optimize("-fschedule-insns2")
28 %:pragma GCC optimize("-fstrict-aliasing")
29 %:pragma GCC optimize("-fstrict-overflow")
30 %:pragma GCC optimize("-falign-functions")
31 %:pragma GCC optimize("-fcse-skip-blocks")
32 %:pragma GCC optimize("-fcse-follow-jumps")
33 %:pragma GCC optimize("-fsched-interblock")
34 %:pragma GCC optimize("-fpartial-inlining")
35 %:pragma GCC optimize("no-stack-protector")
36 %:pragma GCC optimize("-freorder-functions")
37 %:pragma GCC optimize("-findirect-inlining")
38 %:pragma GCC optimize("-fhoist-adjacent-loads")
39 %:pragma GCC optimize("-frerun-cse-after-loop")
40 %:pragma GCC optimize("inline-small-functions")
41 %:pragma GCC optimize("-finline-small-functions")
42 %:pragma GCC optimize("-ftree-switch-conversion")
43 %:pragma GCC optimize("-foptimize-sibling-calls")
44 %:pragma GCC optimize("-fexpensive-optimizations")
45 %:pragma GCC optimize("-funsafe-loop-optimizations")
46 %:pragma GCC optimize("inline-functions-called-once")
47 %:pragma GCC optimize("-fdelete-null-pointer-checks")
48 
49 #include <bits/stdc++.h>
50 using namespace std;
51 
52 const int N = 1e5 + 10;
53 
54 int dep[N], fa[N], w[N];
55 
56 int n, m, q, dis[N];
57 
58 vector<int> G[N];
59 
60 __attribute__((always_inline)) __attribute__((optimize("O2"))) __attribute__((optimize("O3"))) __inline int get(int x) { return x == fa[x] ? x : get(fa[x]); }
61 
62 __attribute__((always_inline)) __attribute__((optimize("O2"))) __attribute__((optimize("O3"))) __inline int merge(int x, int y, int day) {
63     if(dep[x] > dep[y]) swap(x, y);
64     fa[x] = y, w[x] = day, G[y].push_back(x);
65     if(dep[x] == dep[y]) ++ dep[y];
66 }
67 
68 __attribute__((always_inline)) __attribute__((optimize("O2"))) __attribute__((optimize("O3"))) __inline void dfs(int u) {
69     dis[u] = dis[fa[u]] + 1;
70     for(int v: G[u]) dfs(v);
71 }
72 
73 template<typename T> __attribute__((always_inline)) __attribute__((optimize("O2"))) __attribute__((optimize("O3"))) __inline void read(T &x) {
74     char c = x = 0;
75     while(!isdigit(c)) c = getchar();
76     while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
77 }
78 
79 __attribute__((optimize("O2"))) __attribute__((optimize("O3"))) int main() {
80     freopen("pictionary.in", "r", stdin), freopen("pictionary.out", "w", stdout), read(n), read(m), read(q), iota(fa + 1, fa + 1 + n, 1);
81     for(register int i = 1 ; i <= m ; ++ i)
82         for(register int x = m - i + 1, j = x ; j + x <= n ; j += x) {
83             register int u = get(j), v = get(j + x);
84             if(u != v) merge(u, v, i);
85         }
86     for(register int i = 1 ; i <= n ; ++ i) if(fa[i] == i) { dfs(i), fa[i] = 0; break; }
87     for(register int i = 1, u, v ; i <= q ; ++ i) {
88         read(u), read(v);
89         int ans = 0;
90         if(dis[u] < dis[v]) swap(u, v);
91         while(dis[fa[u]] >= dis[v]) ans = max(ans, w[u]), u = fa[u];
92         if(u != v) {
93             while(fa[u] != fa[v]) ans = max(ans, max(w[u], w[v])), u = fa[u], v = fa[v];
94             ans = max(ans, max(w[u], w[v]));
95         }
96         printf("%d\n", ans);
97     }
98 }
JZOJ 5782. 【NOIP提高A组模拟2018.8.8】 城市猎人

 

posted @ 2018-08-09 19:30  KingSann  阅读(174)  评论(0编辑  收藏  举报