博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CodeChef DGCD Dynamic GCD
阅读量:5280 次
发布时间:2019-06-14

本文共 3665 字,大约阅读时间需要 12 分钟。

  • Time limit

    210 ms

  • Code length Limit //内存限制也不说一下,真是的……

    50000 B

  • OS

    Linux

  • Language limit

    C, CPP14, JAVA, PYTH, PYTH 3.6, CS2, PAS fpc, PAS gpc, RUBY, PHP, GO, NODEJS, HASK, SCALA, D, PERL, FORT, WSPC, ADA, CAML, ICK, BF, ASM, CLPS, PRLG, ICON, SCM qobi, PIKE, ST, NICE, LUA, BASH, NEM, LISP sbcl, LISP clisp, SCM guile, JS, ERL, TCL, PERL6, TEXT, PYP3, CLOJ, FS

  • Author

    yellow_agony

  • Tester

    laycurse

  • Tags

    , , , ,

  • Editorial

感想

树上动态gcd的第三题也好了。

  • [x] BZOJ 2257 [
  • [x] BZOJ 5028
  • [x] CodeChef DGCD

解题思路

树剖套线段树。线段树维护区间gcd见 。

另外,注意这题所有点的下标从0开始。

源代码

#include
#include
const int MAXN=5e5+5;int n,m;struct Edge{ int nxt,to;}e[MAXN<<1];int cnt=1,head[MAXN];inline void add(int u,int v){ e[cnt]={head[u],v}; head[u]=cnt++; e[cnt]={head[v],u}; head[v]=cnt++;}struct Tree{ int w; int fa,dep,sz,wson; int top,id;}t[MAXN];void dfs1(int u,int fa){ t[u].fa=fa; t[u].dep=t[fa].dep+1; t[u].sz=1; int maxn=0; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].to; if(v==fa) continue; dfs1(v,u); int temp=t[v].sz; t[u].sz+=temp; if(temp>maxn) { t[u].wson=v; maxn=temp; } }}int id=1;int a[MAXN];void dfs2(int u,int top){ t[u].top=top; t[u].id=id; a[id]=t[u].w; id++; if(t[u].sz==1) return; dfs2(t[u].wson,top); for(int i=head[u];i;i=e[i].nxt) { int v=e[i].to; if(v==t[u].fa||v==t[u].wson) continue; dfs2(v,v); }}int gcd(int a,int b){ if(a<0) a=-a; if(b<0) b=-b; return b?gcd(b,a%b):a;}struct Segtree{ int sum,g;//差分后的sum和gcd}s[MAXN<<2];inline void pushup(int x){ s[x]={s[x<<1].sum+s[x<<1|1].sum,gcd(s[x<<1].g,s[x<<1|1].g)};}void build(int x,int l,int r)//建树前的差分交给主函数{ if(l==r) { s[x]={a[l],a[l]}; return; } int mid=l+r>>1; build(x<<1,l,mid); build(x<<1|1,mid+1,r); pushup(x);}void update(int x,int l,int r,int pos,int k)//单点修改,增加k{ if(l==r) { s[x].sum+=k; s[x].g+=k; return; } int mid=l+r>>1; if(pos<=mid) update(x<<1,l,mid,pos,k); else update(x<<1|1,mid+1,r,pos,k); pushup(x);}int quegcd(int x,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr) return s[x].g; int mid=l+r>>1; if(qr<=mid) return quegcd(x<<1,l,mid,ql,qr); else if(ql>mid) return quegcd(x<<1|1,mid+1,r,ql,qr); else return gcd(quegcd(x<<1,l,mid,ql,qr) , quegcd(x<<1|1,mid+1,r,ql,qr));}int quesum(int x,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr) return s[x].sum; int mid=l+r>>1; if(qr<=mid) return quesum(x<<1,l,mid,ql,qr); else if(ql>mid) return quesum(x<<1|1,mid+1,r,ql,qr); else return quesum(x<<1,l,mid,ql,qr) + quesum(x<<1|1,mid+1,r,ql,qr);}int optf(int u,int v){ int ans=0,l,r,temp; while(t[u].top!=t[v].top) { if(t[t[u].top].dep
t[v].id) std::swap(u,v); l=t[u].id,r=t[v].id; temp=quesum(1,1,n,1,l); if(l!=r) temp=gcd(quegcd(1,1,n,l+1,r),temp); if(!ans) ans=temp; else ans=gcd(temp,ans); return ans;}void optc(int u,int v,int d){ int l,r; while(t[u].top!=t[v].top) { if(t[t[u].top].dep
t[v].id) std::swap(u,v); l=t[u].id,r=t[v].id; update(1,1,n,l,d); if(r
1;i--) a[i]-=a[i-1]; build(1,1,n); scanf("%d",&m); while(m--) { char opt[3]; int u,v,d; scanf("%s%d%d",opt,&u,&v); u++,v++;//下标全部增加1 if(opt[0]=='F') { printf("%d\n",optf(u,v)); } else { scanf("%d",&d); optc(u,v,d); } } return 0;}

转载于:https://www.cnblogs.com/wawcac-blog/p/11321076.html

你可能感兴趣的文章
工作中收集JSCRIPT代码之(下拉框篇)
查看>>
《转载》POI导出excel日期格式
查看>>
code异常处理
查看>>
git - 搭建最简单的git server
查看>>
会话控制
查看>>
推荐一款UI设计软件Balsamiq Mockups
查看>>
Linux crontab 命令格式与详细例子
查看>>
百度地图Api进阶教程-地图鼠标左右键操作实例和鼠标样式6.html
查看>>
游标使用
查看>>
LLBL Gen Pro 设计器使用指南
查看>>
SetCapture() & ReleaseCapture() 捕获窗口外的【松开左键事件】: WM_LBUTTONUP
查看>>
Android 设置界面的圆角选项
查看>>
百度地图api服务端根据经纬度得到地址
查看>>
根据xml生成相应的对象类
查看>>
Android StageFrightMediaScanner源码解析
查看>>
springBoot 项目 jar/war打包 并运行
查看>>
HDU 1501 Zipper
查看>>
打包java程序生成exe
查看>>
八叉树
查看>>
poj 1129 搜索
查看>>