题目

先进行一个转化:

每次花费\(\gcd\limits_{i=l+1}^rB_i\)的代价,可以连\((l,r)\)这一条边。

然后我们需要求\(0\sim n\)的最小生成树。

根据Kruskal的思想,\((0,n)\)这条边一定会被选。

然后根据Prim的思想,对于某个点,我们需要找到其最短的出边。

而显然对于\(i\),它最短的出边为\((i,0)\)或者\((i,n)\)。边权为\(L_i=\gcd\limits_{j=1}^iB_j\)和\(R_i=\gcd\limits_{j=i+1}^nB_j\)。

显然\(L_i\)是单调不增,\(R_i\)是单调不减的。

所以\(\exists p\in[0,n),\forall i\in[0,p],R_i\le L_i,\forall i\in(p,n),L_i\le R_i\)。

我们可以用线段树维护每个区间\([l,r]\)的\(\gcd\limits_{i=l+1}^rB_i\),然后在线段树上二分求出\(p\)。

而题目所给的修改可以直接单点修改。

剩下的就是求\(\sum\limits_{i=0}^pR_i+\sum\limits_{i=p+1}^{n-1}L_i\)。

考虑到\(L_i\)以及\(R_i\)的取值个数是\(\log n\)级别的,我们可以在线段树上暴力找出这些取值以及其对应的区间。

#include<cstdio>
#include<cctype>
#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)
#define ll long long
namespace IO
{
char ibuf[(1<<21)+1],obuf[(1<<21)+1],stk[19],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
void Put(char x){*oS++=x;if(oS==oT)Flush();}
int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
void write(ll x){int top=0;while(x)stk[++top]=(x%10)+48,x/=10;while(top)Put(stk[top--]);Put('\n');}
}
using namespace IO;
int gcd(int n,int m){return !m||!n? n+m:gcd(m,n%m);}
int t[400007];
void build(int p,int l,int r)
{
if(l==r) return (void)(t[p]=read());
build(ls,l,mid),build(rs,mid+1,r),t[p]=gcd(t[ls],t[rs]);
}
void update(int p,int l,int r,int x,int v)
{
if(l==r) return (void)(t[p]=v);
x<=mid? update(ls,l,mid,x,v):update(rs,mid+1,r,x,v);t[p]=gcd(t[ls],t[rs]);
}
int Find(int p,int l,int r,int a,int b)
{
if(l==r) return l;
int x=gcd(a,t[ls]),y=gcd(b,t[rs]);
return x<=y? Find(ls,l,mid,a,y):Find(rs,mid+1,r,x,b);
}
ll cal1(int p,int l,int r,int x,int v)
{
if(l==r) return gcd(t[p],v);
int a=gcd(t[rs],v),b=gcd(t[ls],a);
return x<=mid? cal1(ls,l,mid,x,a):(a==b? 1ll*(mid-l+1)*a:cal1(ls,l,mid,x,a))+cal1(rs,mid+1,r,x,v);
}
ll cal2(int p,int l,int r,int x,int v)
{
if(l==r) return gcd(t[p],v);
int a=gcd(t[ls],v),b=gcd(t[rs],a);
return x>mid? cal2(rs,mid+1,r,x,a):(a==b? 1ll*(r-mid)*a:cal2(rs,mid+1,r,x,a))+cal2(ls,l,mid,x,v);
}
int main()
{
int n=read(),Q=read();
build(1,1,n);
for(int p,v;Q;--Q) p=read(),v=read(),update(1,1,n,p,v),p=Find(1,1,n,0,0),write(cal1(1,1,n,p,0)+cal2(1,1,n,p,0)-t[1]);
return Flush(),0;
}

LOJ576 「LibreOJ NOI Round #2」签到游戏的更多相关文章

  1. 「LibreOJ NOI Round #2」签到游戏

    题目 瞎猜一下我们只要\(n\)次询问就能确定出\(\{A_i\}\)来 感受一下大概是询问的区间越长代价就越小,比如询问\([l,n]\)或\([1,r]\)的代价肯定不会超过\([l,r]\) 所 ...

  2. 「LibreOJ NOI Round #2」不等关系

    「LibreOJ NOI Round #2」不等关系 解题思路 令 \(F(k)\) 为恰好有 \(k\) 个大于号不满足的答案,\(G(k)\) 表示钦点了 \(k\) 个大于号不满足,剩下随便填的 ...

  3. LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿

    二次联通门 : LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 /* LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 dp 记录一下前驱 ...

  4. 「LibreOJ NOI Round #1」验题

    麻烦的动态DP写了2天 简化题意:给树,求比给定独立集字典序大k的独立集是哪一个 主要思路: k排名都是类似二分的按位确定过程. 字典序比较本质是LCP下一位,故枚举LCP,看多出来了多少个独立集,然 ...

  5. #509. 「LibreOJ NOI Round #1」动态几何问题

    下面给出部分分做法和满分做法 有一些奇妙的方法可以拿到同样多的分数,本蒟蒻只能介绍几种常见的做法 如果您想拿18分左右,需要了解:质因数分解 如果您想拿30分左右,需要了解:一种较快的筛法 如果您想拿 ...

  6. #510. 「LibreOJ NOI Round #1」动态几何问题

    题目: 题解: 几何部分,先证明一下 \(KX = \sqrt{a},YL = \sqrt{b}\) 设左侧的圆心为 \(O\) ,连接 \(OK\) ,我们有 \(OK = r\). 然后有 \(r ...

  7. #507. 「LibreOJ NOI Round #1」接竹竿 dp

    题目: 题解: 我们考虑把每对花色相同的牌看作区间. 那么如果我们设 \(f_i\) 表示决策在 \([1,i]\) 内的最优答案. 那么有 \(f_i = max\{max\{(f_{j-1}+\s ...

  8. LOJ#510. 「LibreOJ NOI Round #1」北校门外的回忆(线段树)

    题面 传送门 题解 感谢\(@M\_sea\)的代码我总算看懂题解了-- 这个操作的本质就是每次把\(x\)的\(k\)进制最低位乘\(2\)并进位,根据基本同余芝士如果\(k\)是奇数那么最低位永远 ...

  9. LOJ 510: 「LibreOJ NOI Round #1」北校门外的回忆

    题目传送门:LOJ #510. 题意简述: 给出一个在 \(K\) 进制下的树状数组,但是它的实现有问题. 形式化地说,令 \(\mathrm{lowbit}(x)\) 为在 \(K\) 进制下的 \ ...

随机推荐

  1. JavaScript如何比较两个数组的内容是否相同

    今天意外地发现JavaScript是不能用==或===操作符直接比较两个数组是否相等的. alert([]==[]); // false alert([]===[]); // false 以上两句代码 ...

  2. find命令不递归查询子目录

    [root@dbrg-2 test]# find .  ! -name "." -type d -prune -o -type f -name "*.jpg" ...

  3. zookeeper系列(七)zookeeper的序列化及通讯协议

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败.原创地址http://www.cnblogs.com/leesf456/p/6091208.html尊重作者原创,奇文共欣赏,大家共同学 ...

  4. Rust格式化输出

    打印操作由 https://doc.rust-lang.org/std/fmt/ 里面所定义的一系列宏来处理,包括: format!:将格式化文本写到字符串(String).(译注:字符串是返 回值不 ...

  5. SRS之SrsRtmpConn::service_cycle详解

    1. SrsRtmpConn::service_cycle 当服务器在 conn 线程的开始调用 connect_app 函数接收并解析客户端发送的 connect 消息后,调用该 service_c ...

  6. ILSpy C# language support status

    C# language support status Asynchronous methods 已经支持 Generalized async return types  还不支持 Async main ...

  7. RBAC 权限模型

    RBAC 0 模型 最基本的 MySQL 脚本,没有建立外键约束. /* Navicat Premium Data Transfer Source Server Type : MySQL Source ...

  8. Linux上安装Python3

    1. 安装支持包 yum -y groupinstall "Development tools" yum -y install zlib-devel bzip2-devel ope ...

  9. 删除github上的一个repository

    在学github之初,我们免不了会建立一些简单的repository,那么,如何删掉它们呢? 第一步,打开所要删除的repository,比如:meilin.github.io 第二步,点击setti ...

  10. python pymysql 连接 mysql数据库进行操作

    1.数据库的连接操作 import pymysql conn = pymysql.connect(host=', db='oldboydb') # host表示ip地址,user表示用户名,passw ...