题意:

两个操作,

单点修改

询问一段区间是否能在至多一次修改后,使得区间$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 线程(创建2种方式,锁,死锁,递归锁,GIL锁,守护进程)

    ###############总结############ 线程创建的2种方式(重点) 进程:资源分配单位    线程:cpu执行单位(实体) 线程的创建和销毁的开销特别小 线程之间资源共享,是同一个 ...

  2. Git与GitHub学习笔记(六)使用 Github Pages 管理项目文档

    前言 你可能比较熟悉如何用 Github Pages 来分享你的工作,又或许你看过一堂教你建立你的第一个 Github Pages 网站的教程.近期 Github Pages 的改进使得从不同的数据源 ...

  3. 记一次解决非法参数DDoS攻击的实践

    起因 线上项目突然遭到大量的非法参数攻击,由于历史问题,之前的代码从未对请求参数进行校验. 导致大量请求落到了数据访问层,给应用服务器和数据库都带来了很大压力. 针对这个问题,只能对请求真正到Cont ...

  4. 一些优秀的Python包

    总结一下我使用到的一些比较优秀的Python package =========================通用包========================= Werkzeug itsdan ...

  5. MongoDB统计文档(Document)的数组(Array)中的各个元素出现的次数

    一,问题描述 [使用 unwind 操作符 “解包” Document 里面的Array中的每个元素,然后使用 group 分组统计,最后使用 sort 对分组结果排序] 从 images.json ...

  6. GCC编译器原理(二)------编译原理一:ELF文件(3)

    4.5 String Table:字符串表 字符串表节区包含以 NULL( ASCII 码 0) 结尾的字符序列, 通常称为字符串. ELF 目标文件通常使用字符串来表示符号和节区名称. 对字符串的引 ...

  7. Spring Data 起步

    [Maven 坐标]G A V ……………………………………………………………………………………………………………………………………………… [JDBC] Connection 连接数据库 State ...

  8. zookeeper客户端 zkCli使用及常用命令

    上篇(http://www.cnblogs.com/yangzhenlong/p/8270835.html)zk伪集群搭建好后,使用zkCli连接zk服务 切换到zk1/bin 目录,执行zkCli. ...

  9. ThinkPHP5基础学习

    一.目录与文件结构 二.控制器 三.数据库 四.模型 五.模板

  10. CF 1060E. Sergey and Subway

    题目链接 题意:给你一棵树,然后连接两个有公共邻居的点,问你连完后,任意两点的距离之和. 一开始看这种题,还不怎么会做,借鉴了这位大佬的博客,get到了新技能,当我们求树上任意俩点的距离之时,可以转化 ...