题意:

两个操作,

单点修改

询问一段区间是否能在至多一次修改后,使得区间$GCD$等于$X$

题解:

正确思路;

线段树维护区间$GCD$,查询$GCD$的时候记录一共访问了多少个$GCD$不被X整除的区间即可,大于一个就NO

要注意的是,如果真的数完一整个区间,肯定会超时,因此用一个外部变量存储数量,一旦超过一个,就停止整个查询

#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
using namespace std;
int casn,n,m,k;
class segtree{
#define nd node[now]
#define ndl node[now<<1]
#define ndr node[now<<1|1]
public:
struct segnode {
int l,r;ll gcd,mn;
int mid(){return (r+l)>>1;}
int len(){return r-l+1;}
void update(int x){mn=gcd=x;}
};
vector<segnode> node;
int cnt;
segtree(int n) {node.resize(n<<2|3);maketree(1,n);}
void pushup(int now){
nd.gcd=__gcd(ndl.gcd,ndr.gcd);
nd.mn=min(ndl.mn,ndr.mn);
}
void pushdown(int now){}
void maketree(int s,int t,int now=1){
nd={s,t,0,0};
if(s==t){
ll x;cin>>x;nd.update(x);
return ;
}
maketree(s,nd.mid(),now<<1);
maketree(nd.mid()+1,t,now<<1|1);
pushup(now);
}
void update(int pos,ll x,int now=1){
if(pos>nd.r||pos<nd.l) return ;
if(nd.len()==1){nd.update(x);return ;}
pushdown(now);
update(pos,x,now<<1); update(pos,x,now<<1|1);
pushup(now);
}
int query(int s,int t,ll x){cnt=0;count(s,t,x);return cnt<=1;}
void count(int s,int t,ll x,int now=1){
if(cnt>1||s>nd.r||t<nd.l||nd.gcd%x==0) return ;
if(nd.len()==1) {cnt++; return ;}
count(s,t,x,now<<1);count(s,t,x,now<<1|1);
}
}; int main() {
IO;
cin>>n;
segtree tree(n);
cin>>m;
while(m--){
ll a,b,c,d;
cin>>a;
if(a==1) {
cin>>b>>c>>d;
if(tree.query(b,c,d)) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}else {
cin>>b>>c;
tree.update(b,c);
}
}
return 0;
}

错误思路(会WA8):

如果要修改一次使得$GCD$等于$X$,肯定是修改区间的最小值,线段树维护即可

错误原因在于,$GCD$大于$X$的时候,最小值可能是$X$的倍数,此时不应该修改最小值

#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define mp make_pair
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
#define forn(ii,x) for(int ii=head[x];ii;ii=e[ii].next)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#define inline inline __attribute__( \
(always_inline, __gnu_inline__, __artificial__)) \
__attribute__((optimize("Ofast"))) __attribute__((target("sse"))) \
__attribute__((target("sse2"))) __attribute__((target("mmx")))
#define show(x) cout<<#x<<"="<<x<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define show5(v,w,x,y,z) cout<<#v<<" "<<v<<" "<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl
using namespace std;
const int maxn=1e6+10,maxm=2e6+10;
const ll INF=0x3f3f3f3f3f3f;
const int mod=1e9+7;
const double PI=acos(-1.0);
//head
int casn,n,m,k;
int num[maxn];
class segtree{
#define nd node[now]
#define ndl node[now<<1]
#define ndr node[now<<1|1]
public:
struct segnode {
int l,r;ll gcd,mn;
int mid(){return (r+l)>>1;}
int len(){return r-l+1;}
void update(int x){mn=gcd=x;}
};
vector<segnode> node;
segtree(int n) {node.resize(n<<2|3);maketree(1,n);}
void pushup(int now){
nd.gcd=__gcd(ndl.gcd,ndr.gcd);
nd.mn=min(ndl.mn,ndr.mn);
}
void pushdown(int now){}
void maketree(int s,int t,int now=1){
nd={s,t,0,0};
if(s==t){
ll x;cin>>x;nd.update(x);
return ;
}
maketree(s,nd.mid(),now<<1);
maketree(nd.mid()+1,t,now<<1|1);
pushup(now);
}
void update(int pos,ll x,int now=1){
if(pos>nd.r||pos<nd.l) return ;
if(nd.len()==1){nd.update(x);return ;}
pushdown(now);
update(pos,x,now<<1); update(pos,x,now<<1|1);
pushup(now);
}
ll query_minid(int s,int t,int now=1){
if(nd.len()==1) return s;
if(ndl.mn<=ndr.mn) return query_minid(s,t,now<<1);
else return query_minid(s,t,now<<1|1);
}
ll query_min(int s,int t,int now=1){
if(s>nd.r||t<nd.l) return INF;
if(s<=nd.l&&nd.r<=t) return nd.mn;
return min(query_min(s,t,now<<1),query_min(s,t,now<<1|1));
}
ll query_gcd(int s,int t,int now=1){
if(s>nd.r||t<nd.l) return 0;
if(s<=nd.l&&t>=nd.r)return nd.gcd;
return __gcd(query_gcd(s,t,now<<1),query_gcd(s,t,now<<1|1));
}
}; int main() {
//#define test
#ifdef test
auto _start = chrono::high_resolution_clock::now();
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
// IO;
cin>>n;
segtree tree(n);
cin>>m;
while(m--){
ll a,b,c,d;
cin>>a;
if(a==1) {
cin>>b>>c>>d;
int id=tree.query_minid(b,c);
ll mn=tree.query_min(b,c);
tree.update(id,d);
if(tree.query_gcd(b,c)==d)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
tree.update(id,mn);
}else {
cin>>b>>c;
tree.update(b,c);
}
}
return 0;
}

Codeforces 914D - Bash and a Tough Math Puzzle 线段树,区间GCD的更多相关文章

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

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

  2. [Codeforces 914D] Bash and a Tough Math Puzzle

    [题目链接] https://codeforces.com/contest/914/problem/D [算法] 显然 , 当一个区间[l , r]中为d倍数的数的个数 <= 1 , 答案为Ye ...

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

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

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

    题目链接  Round #458 (Div. 1 + Div. 2, combined)  Problem D 题意  给定一个序列,两种询问:单点修改,询问某个区间能否通过改变最多一个数使得该区间的 ...

  5. cf914D. Bash and a Tough Math Puzzle(线段树)

    题意 题目链接 Sol 直接在线段树上二分 当左右儿子中的一个不是\(x\)的倍数就继续递归 由于最多递归到一个叶子节点,所以复杂度是对的 开始时在纠结如果一段区间全是\(x\)的两倍是不是需要特判, ...

  6. CF914D Bash and a Tough Math Puzzle 线段树+gcd??奇怪而精妙

    嗯~~,好题... 用线段树维护区间gcd,按如下法则递归:(记题目中猜测的那个数为x,改动次数为tot) 1.若子区间的gcd是x的倍数,不递归: 2.若子区间的gcd是x的倍数,且没有递归到叶子结 ...

  7. CodeForces 914DBash and a Tough Math Puzzle(线段树的骚操作)

    D. Bash and a Tough Math Puzzle time limit per test 2.5 seconds memory limit per test 256 megabytes ...

  8. 914D Bash and a Tough Math Puzzle

    传送门 分析 用线段树维护区间gcd,每次查询找到第一个不是x倍数的点,如果这之后还有gcd不能被x整除的区间则这个区间不合法 代码 #include<iostream> #include ...

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

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

随机推荐

  1. python mysql安装&&简单基础sql

    ##############总结############## 1.mysql 介绍 Mysql是开源的,所以你不需要支付额外的费用. Mysql支持大型的数据库.可以处理拥有上千万条记录的大型数据库. ...

  2. Openresty 学习笔记(四)lualocks包管理器安装使用

    Luarocks是一个Lua包管理器,基于Lua语言开发,提供一个命令行的方式来管理Lua包依赖.安装第三方Lua包等,社区比较流行的包管理器之一,另还有一个LuaDist,Luarocks的包数量比 ...

  3. 错误 3 未找到类型“sdk:Label”。请确保不缺少程序集引用并且已生成所有引用的程序集。

    错误: 错误 3 未找到类型“sdk:Label”.请确保不缺少程序集引用并且已生成所有引用的程序集. 错误 1 命名空间“http://schemas.microsoft.com/winfx/200 ...

  4. Silverlight分页

    对于分页,首先要明确一些高效率的策略: 1.一次获取还是每次获取一页的数据 既然考虑了分页,肯定是数据量大,大到不能一页来显示,可能会很多页,我的做法更倾向于,首先要考虑用户可能看的页数,就是说用户可 ...

  5. vertica系列:数据的导入导出

    本文仅涉及 Vertica 导入导出本地文件, 以及两个 Vertica 集群相互导出, 不涉及 Vertica 和 hdfs/Hive 导入导出和互操作. copy 数据导入工具 copy 命令无疑 ...

  6. javascript 正则表达式总结

    为什么要使用正则表达式 正则表达式通过由普通字符和特殊字符组成的文字模板完成对字符串的校验,搜索,替换.在javascript中类似这样 /^1\d{10}$/ 复制代码 上面的这个简单的正则用来匹配 ...

  7. 修改教材P74 一行代码 NineNineTable.java, 让执行结果是个三角形

    修改教材P74 一行代码 NineNineTable.java, 让执行结果是个三角形: 提交在IDEA或命令行中运行结查截图,加上学号水印,没学号的不给成绩 2*9=18 3*9=27 4*9=36 ...

  8. 关于jQuery——attr方法和prop方法获取input的checked属性操作

    经常使用jQuery插件的attr方法获取checked属性值,获取的值的大小为未定义,此时可以用prop方法获取其真实值,下面介绍这两种方法的区别: 1.通过prop方法获取checked属性,获取 ...

  9. BN_batch normalization

    参考: https://zhuanlan.zhihu.com/p/27938792 做法 设,每个batch输入是 (其中每个 都是一个样本, 是batch size) 假如在第一层后加入Batch ...

  10. 缓存dom查询

    为了提高性能缓存dom查询; 页面效果: