HDU 5398 (动态树)
Problem GCD Tree
题目大意
n个点的无向完全图,标号1~n,每条边u-->v 的权值为gcd(u,v),求其最大生成树,输出最大边权和。
n<=10^5,有多个询问。
解题分析
从小到大加入每个点,计算其对答案的贡献。
对于一个点i,只有向它的约数连边才有可能对答案有贡献。
用lct维护一棵最大生成树即可。
参考程序
- #include <map>
- #include <set>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <ctime>
- #include <string>
- #include <vector>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <cassert>
- #include <iostream>
- #include <algorithm>
- #pragma comment(linker,"/STACK:102400000,102400000")
- using namespace std;
- #define N 400008
- #define M 50008
- #define LL long long
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- #define clr(x,v) memset(x,v,sizeof(x));
- #define bitcnt(x) __builtin_popcount(x)
- #define rep(x,y,z) for (int x=y;x<=z;x++)
- #define repd(x,y,z) for (int x=y;x>=z;x--)
- const int mo = ;
- const int inf = 0x3f3f3f3f;
- const int INF = ;
- /**************************************************************************/
- const int maxn = ;
- vector <int> p[N];
- int n,m;
- int fa[N],val[N],mn[N],rev[N],c[N][],st[N],ln[N],rn[N];
- LL ans[maxn];
- bool isroot(int k){
- return c[fa[k]][]!=k && c[fa[k]][]!=k;
- }
- void pushup(int x){
- int l=c[x][],r=c[x][];
- mn[x]=x;
- if (val[mn[l]]<val[mn[x]]) mn[x]=mn[l];
- if (val[mn[r]]<val[mn[x]]) mn[x]=mn[r];
- }
- void pushdown(int x){
- int l=c[x][],r=c[x][];
- if (rev[x]){
- if (l) rev[l]^=;
- if (r) rev[r]^=;
- rev[x]^=;
- swap(c[x][],c[x][]);
- }
- }
- void rotate(int x){
- int y=fa[x],z=fa[y],l,r;
- if (c[y][]==x) l=; else l=; r=l^;
- if (!isroot(y)){
- if (c[z][]==y) c[z][]=x; else c[z][]=x;
- }
- fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
- c[y][l]=c[x][r]; c[x][r]=y;
- pushup(y); pushup(x);
- }
- void splay(int x){
- int top=; st[++top]=x;
- for (int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
- while (top) pushdown(st[top--]);
- while (!isroot(x)){
- int y=fa[x],z=fa[y];
- if (!isroot(y)){
- if (c[y][]==x^c[z][]==y) rotate(x);
- else rotate(y);
- }
- rotate(x);
- }
- }
- void access(int x){
- int t=;
- while (x){
- splay(x);
- c[x][]=t;
- pushup(x);
- t=x; x=fa[x];
- }
- }
- void rever(int x){
- access(x); splay(x); rev[x]^=;
- }
- void link(int u,int v){
- rever(u); fa[u]=v;
- }
- void cut(int u,int v){
- rever(u); access(v); splay(v); fa[c[v][]]=; c[v][]=; pushup(v);
- }
- int find(int u){
- access(u); splay(u);
- while (c[u][]) u=c[u][];
- return u;
- }
- int query(int u,int v){
- rever(u); access(v); splay(v); return mn[v];
- }
- int main(){
- for (int i=;i<=maxn;i++)
- for (int j=i;j<=maxn;j+=i)
- p[j].push_back(i);
- int now=;
- val[]=INF;
- rep(i,,maxn){
- val[++now]=INF;
- mn[now]=now;
- }
- ans[]=;
- LL tmp=;
- for (int u=;u<=maxn;u++){
- for (int i=p[u].size()-;i>=;i--)
- {
- int v=p[u][i];
- int flag=;
- if (find(u)==find(v)){
- int t=query(u,v);
- if (v>val[t]){
- cut(ln[t],t);
- cut(rn[t],t);
- tmp-=val[t];
- flag=;
- }
- else flag=;
- }
- if (flag){
- mn[++now]=now; val[now]=v; ln[now]=u; rn[now]=v;
- link(now,u); link(now,v);
- tmp+=v;
- }
- }
- ans[u]=tmp;
- }
- while (~scanf("%d",&n)){
- printf("%lld\n",ans[n]);
- }
- }
HDU 5398 (动态树)的更多相关文章
- hdu 5398 动态树LCT
GCD Tree Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 5002 (动态树lct)
Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- hdu 5314 动态树
Happy King Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Tot ...
- hdu 4010 动态树 @
kuangbin模板题,看起来十分高大上 /* *********************************************** Author :kuangbin Created Tim ...
- HDU 2475 BOX 动态树 Link-Cut Tree
Box Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) [Problem De ...
- HDU 4010 Query on The Trees (动态树)(Link-Cut-Tree)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(x\) 和 \(y\) 不在同一 ...
- HDU 4836 The Query on the Tree lca || 欧拉序列 || 动态树
lca的做法还是非常明显的.简单粗暴, 只是不是正解.假设树是长链就会跪,直接变成O(n).. 最后跑的也挺快,出题人还是挺阳光的.. 动态树的解法也是听别人说能ac的.预计就是放在splay上剖分一 ...
- HDU 4718 The LCIS on the Tree (动态树LCT)
The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- 动态树LCT小结
最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...
- 如何利用FineReport制作动态树报表
在对数据字段进行分类管理时,利用动态树折叠数据是一个很好的方法,也就是点击数据前面的加号才展开对应下面的数据,如下图.那这样的效果在制作报表时该如何实现呢? 下面以报表工具FineReport为例介绍 ...
随机推荐
- jquery.fullPage.js全屏滚动插件教程演示
css部分(此处需要导入jquery.fullPage.css) <style> .section { text-align: center; font: 50px "Micro ...
- 我的毕业设计——基于安卓和.NET的笔记本电脑远程控制系统
手机端: 电脑端: 答辩完成后会开放代码.
- 今天遇到了批量删除 redis 某个前缀的所有 key,发现只能是这么解决。
redis-cli KEYS "php*" | xargs redis-cli DEL 利用 linux的 管道输出命令 xargs 根据返回结果逐条 删除. 上面这条命令 可 ...
- nginx 配置ci ,tp
#local ciserver { listen 80; server_name ci.local; root E:/test/CodeIgniter/; ...
- ECMAScript6 面向对象 时钟效果
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- js归并排序法
function mergeSort(arr) { var len = arr.length; if(len > 1) { var index = Math.floor(len / 2); le ...
- bzoj2141 树状数组套Treap树
题目大意是在能够改变两个数的位置的情况下计算逆序对数 这因为是动态记录逆序对 本来单纯逆序对只要用树状数组计算即可,但这里因为更新,所以利用TReap树的删点和增加点来进行更新 大致是把每个树状数组所 ...
- 搬运:Python for Windows——监控Windows某个目录下文件的变化
https://win32com.goermezer.de/content/view/286/285/ 这个网站真是给力,不多说,代码直接搬运过来,还有我的测试结果,拿走不谢! import os i ...
- 嵌入式 python异常except语句用法与引发异常 zz
http://blog.sina.com.cn/s/blog_8795b0970101dj0a.html
- golang实现随机数
package main import ( "fmt" "time" "math/rand" ) func main() { r := ra ...