LCA + 并查集 Happy Tree Party codeforces593D
来源:互联网 发布:一搜网络一搜同志0731 编辑:程序博客网 时间:2024/06/06 06:33
一个64位的数,最多在被大于1的数整除64次后就变为0
所以对于每次访问,我们最多除64次
那么我们就要将为1的路压缩,使用并查集
每次访问使用lca,找到公共祖先lc,然后u->lc,v->lc,访问这两条路
记得并查集的时候要用
return par[u] == u ? u : par[u] = find(par[u]);
不要用
return par[u] == u ? u : find(par[u]);
后者也能查询,但是前者再并在一起省时,不然会t的
/********************************************Author :CrystalCreated Time :File Name :********************************************/#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#include <cstring>#include <climits>#include <string>#include <vector>#include <cmath>#include <stack>#include <queue>#include <set>#include <map>#include <sstream>#include <cctype>using namespace std;typedef long long ll;typedef pair<int ,int> pii;#define MEM(a,b) memset(a,b,sizeof a)#define CLR(a) memset(a,0,sizeof a);const int inf = 0x3f3f3f3f;const int MOD = 1e9 + 7;//#define LOCAL#define maxn 500005int root = 1;int head[maxn],nxt[maxn],pnt[maxn];int par[maxn];ll cost[maxn];int dep[maxn],far[maxn],p[maxn][30];ll path[maxn][30];int dis[maxn];int u[maxn];int v[maxn];ll c[maxn];int cnt = 0;int n,q;int find(int u){return par[u] == u ? u : par[u] = find(par[u]);}void addedge(int u,int v,ll c){pnt[cnt] = v;nxt[cnt] = head[u];cost[cnt] = c;head[u] = cnt++;}int llog = 20;void dfs(int u,int f,int d){dep[u] = d;p[u][0] = f;for(int i=head[u];~i;i = nxt[i]){int v = pnt[i];if(v == f)continue;path[v][0] = cost[i];dfs(v, u, d+1); }}void init(){dfs(root, -1, 0);for(int i=0;i+1<llog;i++){for(int v=1;v<=n;v++){if(p[v][i] == -1)p[v][i+1] = -1;else p[v][i+1] = p[p[v][i]][i];}}}int lca(int u,int v){if(dep[u] > dep[v])swap(u,v);for(int i=0;i<llog;i++){if(dep[v]-dep[u] >> i & 1){v = p[v][i];}}if(u == v)return u;for(int i=llog - 1;i != -1;i--){if(p[u][i] != p[v][i]){u = p[u][i];v = p[v][i];}}return p[u][0];}ll solve(int u,int v,ll x){//cout << u <<v <<x << endl;int cnt = 0;while(x && dep[u] < dep[v] && cnt < 65){v = find(v);if(dep[u] >= dep[v])break;x /= path[v][0];v = p[v][0];cnt++;}return x;}int main(){#ifdef LOCALfreopen("in.txt", "r", stdin);//freopen("out.txt","w",stdout);#endifcin >> n >> q;MEM(head,-1);for(int i=1;i<n;i++){scanf("%d%d%lld",&u[i],&v[i],&c[i]);addedge(u[i],v[i],c[i]);addedge(v[i],u[i],c[i]);}for(int i=1;i<=n;i++)par[i] = i;init();for(int i=1;i<n;i++){if(c[i]==1){if(dep[u[i]] > dep[v[i]]){par[u[i]] = find(v[i]);}else{par[v[i]] = find(u[i]);}}}for(int i=1;i<=q;i++){int f;cin >> f;if(f==1){int u,v;ll x;scanf("%d%d%lld",&u,&v,&x);int lc = lca(u,v);//cout << lc << endl;x = solve(lc,u,x);x = solve(lc,v,x);printf("%lld\n",x);}else{int load;ll x;scanf("%d%lld",&load,&x);int a = u[load];int b = v[load];if(dep[a]>dep[b]){path[a][0] = x;}else{path[b][0] = x;}if(x == 1){if(dep[a]>dep[b]){par[a] = find(b);}else par[b] = find(a);}}}return 0;}
0 0
- LCA + 并查集 Happy Tree Party codeforces593D
- codeforces 593 D. Happy Tree Party (LCA + 并查集)
- codeforces 593D Happy Tree Party Lca+并查集
- codeforces #329 D. Happy Tree Party (LCA+并查集 || 树链剖分)
- CodeForces 593D Happy Tree Party(树链剖分(边权) or LCA+并查集)
- 【Codeforces Round 329 (Div 2) D】【LCA+并查集路径压缩】Happy Tree Party 除上两点间路径全部权值
- [CodeForces 593D]Happy Tree Party[LCA][路径压缩]
- 并查集 codeforces party
- [树链剖分] CF593D. Happy Tree Party
- poj3728并查集+LCA
- Tree(并查集)
- 【13.91%】【codeforces 593D】Happy Tree Party
- CodeForces 593D Happy Tree Party
- Codeforces 593D-Happy Tree Party
- LCA算法--并查集应用
- poj 3728(LCA+并查集应用)
- HDU2874并查集+(LCA-RMQ)
- POJ_3694 Network Tarjin + LCA + 并查集
- 歪打正着;屏蔽网页里的输入;
- Principal component analysis
- POJ 4083 我爱北大
- [github]github实战 for mac
- Objective-C tips
- LCA + 并查集 Happy Tree Party codeforces593D
- 搭建Nginx+Java环境(转)
- copyFromLocal异常DataNode启动不了
- javaScript cookies
- 枚举类型转换
- Apche Kafka 的生与死 – failover 机制详解
- java程序员第十七课 -JDBC01
- 关于tomcat是否有必要设置环境变量
- Masonry介绍与使用实践:快速上手Autolayout