CodeChef DGCD Dynamic GCD
- Time limit
210 ms
Code length Limit //内存限制也不说一下,真是的……
50000 BOS
LinuxLanguage 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, FSAuthor
yellow_agonyTester
laycurseTags
hard, heavy-light, july12, number-theory, yellow_agony
感想
树上动态gcd的第三题也好了。
- [x] BZOJ 2257 [JSOI2009]瓶子和燃料
- [x] BZOJ 5028 小z的加油站
- [x] CodeChef DGCD Dynamic GCD
解题思路
树剖套线段树。线段树维护区间gcd见 小z的加油站 。
另外,注意这题所有点的下标从0开始。
源代码
#include<stdio.h>
#include<algorithm>
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[t[v].top].dep) std::swap(u,v);
l=t[t[u].top].id;
r=t[u].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);
u=t[t[u].top].fa;
}
if(t[u].id>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[t[v].top].dep) std::swap(u,v);
l=t[t[u].top].id;
r=t[u].id;
update(1,1,n,l,d);
if(r<n) update(1,1,n,r+1,-d);
u=t[t[u].top].fa;
}
if(t[u].id>t[v].id) std::swap(u,v);
l=t[u].id,r=t[v].id;
update(1,1,n,l,d);
if(r<n) update(1,1,n,r+1,-d);
}
int main()
{
freopen("test.in","r",stdin);
scanf("%d",&n);
for(int i=1,u,v;i<n;i++)
{
scanf("%d%d",&u,&v);
u++,v++;//下标全部增加1
add(u,v);
}
for(int i=1;i<=n;i++)
scanf("%d",&t[i].w);
dfs1(1,0);
dfs2(1,1);
for(int i=n;i>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;
}
CodeChef DGCD Dynamic GCD的更多相关文章
- codechef Dynamic GCD [树链剖分 gcd]
Dynamic GCD 题意:一棵树,字词树链加,树链gcd 根据\(gcd(a,b)=gcd(a,a-b)\) 得到\(gcd(a_1, a_2, ..., a_i) = gcd(a_1, a_1- ...
- CC DGCD:Dynamic GCD——题解
https://vjudge.net/problem/CodeChef-DGCD https://www.codechef.com/problems/DGCD 题目大意: 给一颗带点权的树,两个操作: ...
- CodeChef Dynamic GCD
嘟嘟嘟vjudge 我今天解决了一个历史遗留问题! 题意:给一棵树,写一个东西,支持一下两种操作: 1.\(x\)到\(y\)的路径上的每一个点的权值加\(d\). 2.求\(x\)到\(y\)路径上 ...
- CodeChef DGCD
You're given a tree on N vertices. Each vertex has a positive integer written on it, number on the i ...
- Dynamic Gcd
树链剖分+差分 直接区间加显然是不行的,由于gcd(a,b,c)=gcd(a,a-b,b-c),那么我们对这些数差分,然后就变成单点修改.原本以为这道题很简单,没想到这么麻烦,就膜了发代码. 首先我们 ...
- CodeChef Sereja and GCD
Sereja and GCD Problem code: SEAGCD Submit All Submissions All submissions for this problem ar ...
- scau 2015寒假训练
并不是很正规的.每个人自愿参与自愿退出,马哥找题(马哥超nice么么哒). 放假第一周与放假结束前一周 2015-01-26 http://acm.hust.edu.cn/vjudge/contest ...
- BZOJ 5028 小z的加油站
bzoj链接 Time limit 10000 ms Memory limit 262144 kB OS Linux 感想 树上动态gcd的第二题也好了. [x] BZOJ 2257 [JSOI200 ...
- 洛谷 P4571 BZOJ 2257 [JSOI2009]瓶子和燃料
bzoj题目链接 上面hint那里是选择第2个瓶子和第3个瓶子 Time limit 10000 ms Memory limit 131072 kB OS Linux Source Jsoi2009 ...
随机推荐
- 纯JS实现多图片上传(在layui框架中)
HTML代码 <form id="form1" class="layui-form layui-form-pane" action="{:url ...
- Java实验报告四
一.实验目的 (1)掌握类的继承方法: (2)变量的继承和覆盖,方法的继承.重载和覆盖实现: 二.实验内容 1)实验代码 import java.util.Scanner; public class ...
- 在CentOS 8 Linux中安装使用Cockpit服务器管理软件
在本文中,我们将帮助您在CentOS 8服务器中安装Cockpit Web 控制台,以管理和监视本地系统以及网络环境中的Linux服务器.您还将学习如何将远程Linux主机添加到Cockpit并在Ce ...
- C语言作业11
问题 答案 这个作业属于那个课程 C语言程序设计 这个作业要求在哪里 https://www.cnblogs.com/galen123/p/11996995.html 我在这个课程的目标是 在学好C语 ...
- PTA 7-20 表达式转换
转自:https://www.cnblogs.com/yuxiaoba/p/8399934.html 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.日常使用的算术表达式是采用中缀表示法,即二元 ...
- C++中setiosflags()的用法
cout<<setiosflags(ios::fixed)<<setiosflags(ios::right)<<setprecision(2); setiosfla ...
- numpy伪随机数的生成
numpy伪随机数的生成 normal函数 可以用normal来得到一个标准正态分布的4×4样本数组 >>> import numpy as np >>> samp ...
- <<C++ Primer>> 第 5 章 语句
术语表 第 5 章 语句 块(block): 包围在花括号内的由 0 条或多条语句组成的序列.块也是一条语句,所以只要是能使用语句的地方,就可以使用块. break语句(break statem ...
- python简介与简单入门
1.计算机基础 计算机组成: 输入输出设备内. 存储器 .cpu .电源 .显卡 中央处理器(cpu) 处理各种数据 相当于人的大脑 内存 存储数据 相当于临时记忆 硬盘 存储数据 相当于人的永久记忆 ...
- Maven 相关功能介绍
一: Maven环境隔离