一棵树,每个点上有三个数。求一条路径上的众数以及其出现次数。
强制在线
n ≤ 8 × 1 0 4 , q ≤ 1 0 5 nleq8times 10^4,qleq10^5 n≤8×104,q≤105
时限:10s
Infleaking:垃圾分块模板题,还硬生生加个3的常数
以上两种操作都能期望每一块(被关键点隔开的连通块)直径不会超过 O ( n ) O(sqrt n) O(n )
O ( q n ) O(qsqrt n) O(qn )
#include <bits/stdc++.h>
using namespace std;
const int N = 8e4 + 10, BLOCK_SIZE = 300, KEY_NODE_CNT = N / BLOCK_SIZE * 2;
int py,n,a[N][3],xorsum;
int final[N],nex[N*2],to[N*2],tot;
void link(int x, int y) {to[++tot] = y, nex[tot] = final[x], final[x] = tot;
}int g[N][18], dep[N];
vector<int> key;
int pre[KEY_NODE_CNT][N],sz[N];
int dfn[N], stm, R[N];void dfs(int x) {dfn[x] = ++ stm;dep[x]=dep[g[x][0]]+1;for(int i=1;i<17;i++)g[x][i]=g[g[x][i - 1]][i - 1];for(int i = final[x]; i; i = nex[i]) {int y = to[i];if (y != g[x][0]) {g[y][0] = x;dfs(y);sz[x] += sz[y];}}sz[x]++;if(sz[x] >= BLOCK_SIZE){key.push_back(x);sz[x]=0;}R[x] = stm;
}int lca(int x, int y) {if(dep[x]<dep[y])swap(x,y);for(int i=17;~i;i--)if(dep[g[x][i]]>=dep[y])x=g[x][i];if(x==y)return x;for(int i=17;~i;i--)if(g[x][i]!=g[y][i])x=g[x][i],y=g[y][i];return g[x][0];
}int no[N],kfa[N],d[N],keycnt[N];
pair<int,int> cnt[N], now;
pair<int,int> pro[KEY_NODE_CNT][KEY_NODE_CNT];void init(int x, int neark) {for(int i = 0; i < 3; i++) d[a[x][i]]++;if(no[x] != 0){memcpy(pre[no[x]], d, sizeof d);neark = x;}kfa[x] = neark;keycnt[x] = keycnt[g[x][0]] + (no[x] != 0);for(int i = final[x]; i; i = nex[i]) {int y = to[i]; if (y != g[x][0]) {init(y, neark);}}for(int i = 0; i < 3; i++) d[a[x][i]]--;
}int ori;
void calc(int x, int from) {pair<int,int> las_ans = now;for(int i : a[x]) {cnt[i].first++;if(cnt[i] > now) now=cnt[i];}if (no[x] != 0) {pro[ori][no[x]] = now;}for(int i = final[x]; i; i = nex[i]) {int y = to[i]; if (y != from) {calc(y, x);}}for(int i : a[x]) cnt[i].first--;now = las_ans;
}pair<int,int> brute_force(int u, int v) {pair<int,int> ans = make_pair(0, 0);int e = lca(u,v);for(int i : a[e]) {cnt[i].first++;if (cnt[i] > ans) ans = cnt[i];}for(int z = u; z != e; z = g[z][0]) {for(int i : a[z]) {cnt[i].first++;if (cnt[i] > ans) ans = cnt[i];}}for(int z = v; z != e; z = g[z][0]) {for(int i : a[z]) {cnt[i].first++;if (cnt[i] > ans) ans = cnt[i];}}for(int i : a[e]) cnt[i].first--;for(int z = u; z != e; z = g[z][0]) {for(int i : a[z]) cnt[i].first--;}for(int z = v; z != e; z = g[z][0]) {for(int i : a[z]) cnt[i].first--;}return ans;
}int jump(int st, int up) {for(int i = 17; ~i; i--) if (keycnt[g[st][i]] - keycnt[up] > 0) {st = g[st][i];}return st;
}int query(int u, int g, int v, int w) {int ret = pre[no[u]][w] + pre[no[v]][w] - 2 * pre[no[g]][w];for(int i : a[g]) ret += i == w;return ret;
}
vector<int> todel;int main() {freopen("mode.in","r",stdin);freopen("mode.out","w",stdout); cin>>py>>n;for(int i=1;i<=n;i++){scanf("%d %d %d",&a[i][0],&a[i][1],&a[i][2]);}for(int i=1;i<n;i++){int u,v;scanf("%d %d",&u,&v);link(u,v),link(v,u);}dfs(1);key.push_back(1);int tmp = key.size();for(int i = 0; i < tmp; i++) {for(int j = i + 1; j < tmp; j++) {key.push_back(lca(key[i], key[j]));}}sort(key.begin(), d());size(unique(key.begin(), d()) - key.begin());for(int i = 0; i < key.size(); i++) {no[key[i]] = i + 1;}init(1,0);for(int i = 1; i <= n; i++) cnt[i].second = -i;for(int x : key) ori = no[x], calc(x, 0);int q; cin >> q;for(int i = 1; i <= q; i++) {int u,v; scanf("%d %d",&u,&v);if (py) u^=xorsum, v^=xorsum;pair<int,int> ans = make_pair(0,0);int e = lca(u, v);if (keycnt[u] + keycnt[v] - 2 * keycnt[e] + (no[e] != 0) < 2) {ans = brute_force(u, v);} else {if (dfn[u] > dfn[v]) swap(u, v);int x = 0, y = 0;//u-x-y-vint flagu = 0, flagv = 0;if (keycnt[u] != keycnt[e]) x = kfa[u];else x = jump(v, e), flagu = 1;if (keycnt[v] != keycnt[e]) y = kfa[v];else y = jump(u, e), flagv = 1;todel.clear();ans = pro[no[x]][no[y]];int ee = lca(x, y);for(int z = u; z != e && z != x; z = g[z][0]) {todel.push_back(z);for(int i : a[z]) {cnt[i].first++;pair<int,int> fact = cnt[i];fact.first += query(x, ee, y, i);if (fact > ans) ans = fact;}}for(int z = v; z != e && z != y; z = g[z][0]) {todel.push_back(z);for(int i : a[z]) {cnt[i].first++;pair<int,int> fact = cnt[i];fact.first += query(x, ee, y, i);if (fact > ans) ans = fact;}}if (flagu) {for(int z = g[x][0]; z != g[e][0]; z = g[z][0]) {todel.push_back(z);for(int i : a[z]) {cnt[i].first++;pair<int,int> fact = cnt[i];fact.first += query(x, ee, y, i);if (fact > ans) ans = fact;}}}if (flagv) {for(int z = g[y][0]; z != g[e][0]; z = g[z][0]) {todel.push_back(z);for(int i : a[z]) {cnt[i].first++;pair<int,int> fact = cnt[i];fact.first += query(x, ee, y, i);if (fact > ans) ans = fact;}}}for(int z : todel) {for(int i : a[z]) cnt[i].first--;}}xorsum ^= ans.first ^ -ans.second;printf("%d %dn", ans.first, -ans.second);}
}
本文发布于:2024-01-28 05:29:22,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063909665130.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |