Codeforce 914 D. Bash and a Tough Math Puzzle 解析(線段樹、數論)

今天我們來看看CF914D

題目連結

題目

給你一個長度為\(n\)的數列\(a\),每次玩家會選擇一個區間猜\(g.c.d.\)的值,或者改變數列中的某個數字。而猜中不一定要完全準確,如果玩家能夠改動一個區間中的數字讓\(g.c.d.\)完全猜中也是可以的。

前言

我對線段樹還是不熟阿,一開始一直感覺\(g.c.d.\)沒辦法用線段樹維護...

想法

上模板,從維護區間和的模板改成維護\(g.c.d.\)(這就是為什麼我code中的元素修改函式叫做\(add\))。

接著注意到一件事,猜中的條件是:假設區間中有\(k\)個數字,只要其中\(k-1\)個數字可以被\(val\)(\(val\stackrel{def}{=}\)玩家猜的數字)整除就可以了(如果這\(k-1\)個數字的\(g.c.d.\ge val\),那麼只要把最後那個數字改成\(val\)就好)。

一開始我就直接這樣實作,每次從\(root\)開始往下找有幾個數字可以被整除,整個區間都看過以後再來檢查是否\(\ge k-1\),但是發現這樣會TLE。

查網路後發現我們必須用一個全域變數去計算:有多少在區間中數字不可被整除,如果發現數量\(>1\)就要馬上跳離搜尋,如此一來就不會TLE了。

(\(almost\)函式是這題的重點,寫法和模板有點差異,要小心實作。)

程式碼:

const int _n=5e5+10;
int n,a[_n],q,tt,tot=0;
namespace Seg{
int nn;
int t[_n<<2];
void pull(int v){t[v]=__gcd(t[2*v+1],t[2*v+2]);}
void apply(int v, int val){t[v]=val;}
void build(int v, int l, int r){
if(l+1==r)t[v]=a[l];
else{int m=(l+r)>>1;build(2*v+1,l,m),build(2*v+2,m,r);pull(v);}
}
void add(int v,int l,int r,int ql,int qr,int val){
if(r<=ql or qr<=l)return;
else if(ql<=l and r<=qr)apply(v,val);
else{
int m=(l+r)>>1;
add(2*v+1,l,m,ql,qr,val),add(2*v+2,m,r,ql,qr,val);
pull(v);
}
}
void add(int pos,ll val){add(0,0,nn,pos,pos+1,val);}
void init(int n_){nn=n_;build(0,0,nn);}
void almost(int v,int l,int r,int ql,int qr,int val){
if(tot>1)return;
if(r<=ql or qr<=l)return;
else if(ql<=l and r<=qr and t[v]%val==0)return;
else{
if(l+1==r){tot++;return;}
int m=(l+r)>>1;
almost(2*v+1,l,m,ql,qr,val),almost(2*v+2,m,r,ql,qr,val);
}
}
}
main(void) {cin.tie(0);ios_base::sync_with_stdio(0);
cin>>n;rep(i,0,n)cin>>a[i]; cin>>q;
Seg::init(n);
while(q--){
cin>>tt;
if(tt==1){
int l,r,x;cin>>l>>r>>x;l--,r--;
tot=0;Seg::almost(0,0,n,l,r+1,x);
if(tot<=1)cout<<"YES\n";
else cout<<"NO\n";
}else{
int i,y;cin>>i>>y;i--;
Seg::add(i,y);
}
}
return 0;
}

標頭、模板請點Submission看

Submission

D. Bash and a Tough Math Puzzle 解析(線段樹、數論)的更多相关文章

  1. CF 914 D. Bash and a Tough Math Puzzle

    D. Bash and a Tough Math Puzzle http://codeforces.com/contest/914/problem/D 题意: 单点修改,每次询问一段l~r区间能否去掉 ...

  2. Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论

    Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变 ...

  3. E. Copying Data 解析(線段樹)

    Codeforce 292 E. Copying Data 解析(線段樹) 今天我們來看看CF292E 題目連結 題目 給你兩個陣列\(a,b\),有兩種操作:把\(a\)的一段複製到\(b\),或者 ...

  4. Codecraft-18 and Codeforces Round #458:D,Bash and a Tough Math Puzzle

    题目传送门 题目大意:Bash喜欢对数列进行操作.第一种操作是询问l~r区间内的gcd值是否几乎为x,几乎为表示能否至多修改一个数达到.第二种操作是将ai修改为x.总共Q个询问,N个数. Soluti ...

  5. Codeforces 914D - Bash and a Tough Math Puzzle 线段树,区间GCD

    题意: 两个操作, 单点修改 询问一段区间是否能在至多一次修改后,使得区间$GCD$等于$X$ 题解: 正确思路; 线段树维护区间$GCD$,查询$GCD$的时候记录一共访问了多少个$GCD$不被X整 ...

  6. Codeforces.914D.Bash and a Tough Math Puzzle(线段树)

    题目链接 \(Description\) 给定一个序列,两种操作:一是修改一个点的值:二是给一个区间\([l,r]\),问能否只修改一个数使得区间gcd为\(x\). \(Solution\) 想到能 ...

  7. 2018.12.08 codeforces 914D. Bash and a Tough Math Puzzle(线段树)

    传送门 线段树辣鸡题. 题意简述:给出一个序列,支持修改其中一个数,以及在允许自行修改某个数的情况下询问区间[l,r][l,r][l,r]的gcdgcdgcd是否可能等于一个给定的数. 看完题就感觉是 ...

  8. Bash and a Tough Math Puzzle CodeForces - 914D (线段树二分)

    大意:给定序列, 单点修改, 区间询问$[l,r]$内修改至多一个数后$gcd$能否为$x$ 这题比较有意思了, 要注意到询问等价于$[l,r]$内最多有1个数不为$x$的倍数 可以用线段树维护gcd ...

  9. [CF914D]Bash and a Tough Math Puzzle

    给定一个数列$a_1,a_2,...,a_n$,支持两种操作 1 l r x,猜测数列中[l,r]位置上的数的最大公约数$x$,判断这个猜测是否是接近正确的.如果我们可以在数列[l,r]位置中改动至多 ...

随机推荐

  1. st表、RMQ和LCA

    int lca(int x,int y) { if(de[x]<de[y]) swap(x,y); int d=de[x]-de[y]; for(int i=log2(d);i>=0;i- ...

  2. 简单说说Restful API

    前言: 最近一段时间,一直在低头敲代码,开发平台对外交互的API接口,功能已经大体完成了,回过头来看看自己的接口设计文档,不胜感慨,想当初自己也是为"接口名称"想破了脑袋,各种百度 ...

  3. 对抗生成网络 Generative Adversarial Networks

    1. Basic idea 基本任务:要得到一个generator,能够模拟想要的数据分布.(一个低维向量到一个高维向量的映射) discriminator就像是一个score function. 如 ...

  4. 错误: 在类中找不到 main 方法, 请将 main 方法定义为: &#160; &#160;public static void main(String[] args) 否则 JavaFX 应用程序类必须扩展javafx.application.Application 。

    昨天在eclipse编写JAVA程序时,遇到一个问题: 错误: 在类中找不到 main 方法, 请将 main 方法定义为:    public static void main(String[] a ...

  5. Emgu.CV怎么加载Bitmap

    EmguCV 在4.0.1版本之后没办法用Bitmap创建Image了. 我给大家说下 EmguCV怎么加载Bitmap 下边是 EmguCV 官方文档写的,意思是从4.0.1以后的版本不能直接Bit ...

  6. 神奇的字符串匹配:扩展KMP算法

    引言 一个算是冷门的算法(在竞赛上),不过其算法思想值得深究. 前置知识 kmp的算法思想,具体可以参考 → Click here trie树(字典树). 正文 问题定义:给定两个字符串 S 和 T( ...

  7. HTML中css水平居中的几种方式

    1. 子元素为行内元素时,父元素使用 text-align: center; 实现子元素的水平居中: 2. 子元素为块级元素时, 2.1. 将子元素设置 margin: 0 auto; 实现居中: 2 ...

  8. MATLAB中conv2的详细用法 (以及【matlab知识补充】conv2、filter2、imfilter函数原理)

    转载: 1.https://blog.csdn.net/jinv5/article/details/52874880 2.https://blog.csdn.net/majinlei121/artic ...

  9. arduino中驱动 步进电机

    参考:https://www.arduino.cn/thread-75936-1-1.html 知识点:    步进电机是一种将电脉冲转化为角位移的执行机构.通俗一点讲:当步进驱动器接收到一个脉冲信号 ...

  10. Android和CraigDJ

    下载HTML source - 46.8 KB 下载APK - 8.1 MB Introduction  大家好,欢迎来到我的Android应用程序项目! 我必须承认,我仍然对原生安卓环境几乎一无所知 ...