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 ...
随机推荐
- Akka系列(七):Actor持久化之Akka persistence
前言.......... 我们在使用Akka时,会经常遇到一些存储Actor内部状态的场景,在系统正常运行的情况下,我们不需要担心什么,但是当系统出错,比如Actor错误需要重启,或者内存溢出,亦或者 ...
- XCode8.3真机调试设置
本文使用XCode8.3.3 首先XCode->Preferncs,进入下面的界面 点击左下角“+”号,并输入账号,然后点击Manage Certificates,左下角添加IOS develo ...
- 红帽学习笔记[RHCE]OpenLDAP 服务端与客户端配置
目录 OpenLDAP 服务端与客户端配置 关于LDIF 一个LDIF基本结构一个条目 属性 Object的类型 服务端 安装 生成证书 生成默认数据 修改基本的配置 导入基础数据 关于ldif的格式 ...
- 迭代器与iterable
迭代器与iterable 最近在学习ES6,有两个概念一直纠缠不清,就是迭代器与iterable,查阅了一些资料,简单来说迭代器就是包含next方法的对象,而iterable是包含可以在其值上迭代的迭 ...
- 【中间件】Kafka 学习 01
KafKa 博客教程-1 博客教程-2 kafka简介 kafka起源 Kafka是由LinkedIn开发并开源的分布式消息系统,2012年捐赠给Apache基金会,采用Scala语言,运行在JVM中 ...
- 2-django配置
一.settings.py配置 1.时区配置 现在看到的界面是英文的,将 LANGUAGE_CODE = 'en-us' 改为 LANGUAGE_CODE = 'zh-Hans '就可以看到如下界面 ...
- cs244a-Introduction to Computer Networking-Unit1
Unit 1 学习目标: how an application use the Internet The structure of the Internet:The 4 layer model The ...
- drf三大认证解析
目录 三大认证 认证模块: 权限模块 频率模块 RABC author组件 认证权限六表. Content_type 认证与权限工作原理+自定义认证类 自定义权限类 admin关联自定义用户表 前后台 ...
- JS计算两个经纬度的距离
var mapNumberUtil = {}; /** * 计算两个经纬度的距离(千米) */mapNumberUtil.getDistance = function(lat1, lng1, lat2 ...
- Android 关于悬浮窗权限的问题
正常情况下的处理: dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)以及在清单文件中添加 <use ...