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\)函式是這題的重點,寫法和模板有點差異,要小心實作。)

程式碼:

  1. const int _n=5e5+10;
  2. int n,a[_n],q,tt,tot=0;
  3. namespace Seg{
  4. int nn;
  5. int t[_n<<2];
  6. void pull(int v){t[v]=__gcd(t[2*v+1],t[2*v+2]);}
  7. void apply(int v, int val){t[v]=val;}
  8. void build(int v, int l, int r){
  9. if(l+1==r)t[v]=a[l];
  10. else{int m=(l+r)>>1;build(2*v+1,l,m),build(2*v+2,m,r);pull(v);}
  11. }
  12. void add(int v,int l,int r,int ql,int qr,int val){
  13. if(r<=ql or qr<=l)return;
  14. else if(ql<=l and r<=qr)apply(v,val);
  15. else{
  16. int m=(l+r)>>1;
  17. add(2*v+1,l,m,ql,qr,val),add(2*v+2,m,r,ql,qr,val);
  18. pull(v);
  19. }
  20. }
  21. void add(int pos,ll val){add(0,0,nn,pos,pos+1,val);}
  22. void init(int n_){nn=n_;build(0,0,nn);}
  23. void almost(int v,int l,int r,int ql,int qr,int val){
  24. if(tot>1)return;
  25. if(r<=ql or qr<=l)return;
  26. else if(ql<=l and r<=qr and t[v]%val==0)return;
  27. else{
  28. if(l+1==r){tot++;return;}
  29. int m=(l+r)>>1;
  30. almost(2*v+1,l,m,ql,qr,val),almost(2*v+2,m,r,ql,qr,val);
  31. }
  32. }
  33. }
  34. main(void) {cin.tie(0);ios_base::sync_with_stdio(0);
  35. cin>>n;rep(i,0,n)cin>>a[i]; cin>>q;
  36. Seg::init(n);
  37. while(q--){
  38. cin>>tt;
  39. if(tt==1){
  40. int l,r,x;cin>>l>>r>>x;l--,r--;
  41. tot=0;Seg::almost(0,0,n,l,r+1,x);
  42. if(tot<=1)cout<<"YES\n";
  43. else cout<<"NO\n";
  44. }else{
  45. int i,y;cin>>i>>y;i--;
  46. Seg::add(i,y);
  47. }
  48. }
  49. return 0;
  50. }

標頭、模板請點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. 提权 EXP

    windows: 漏洞列表 #Security Bulletin #KB #Description #Operating System CVE-2017-0213 [Windows COM Eleva ...

  2. shiro安全框架和spring整合

    上干货......... 整合spring的配置文件 <?xml version="1.0" encoding="UTF-8"?><beans ...

  3. 手对手的教你用canvas画一个简单的海报

    啦啦啦,首先说下需求,产品想让用户在我们app内,分享一张图片到微信.qq等平台.图片中包含用户的姓名.头像.和带着自己信息的二维码.然后,如何生成这张海报呢~~~首先我们老大告诉我有一个插件叫htm ...

  4. Python-信号量和线程池-semaphore ThreadPollExector

    信号量 其实本质上是锁,Lock是单锁,信号量是指定多把锁,也就是说通过信号量指定多个数线程可以访问相同资源,一般情况下读操作可以有多个,但写操作同时只有一个 信号量模块 semaphore # 使用 ...

  5. pytorch和tensorflow的爱恨情仇之参数初始化

    pytorch和tensorflow的爱恨情仇之基本数据类型 pytorch和tensorflow的爱恨情仇之张量 pytorch和tensorflow的爱恨情仇之定义可训练的参数 pytorch版本 ...

  6. python中numpy.savetxt 参数

    转载:https://blog.csdn.net/qq_36535820/article/details/99543188 numpy.savetxt 参数 numpy.savetxt(fname,X ...

  7. c++ 十进制、十六进制和BCD的相互转换,与打印printf,与函数调用

    转载: https://blog.csdn.net/sjhuangx/article/details/49947179   c++ 十进制.十六进制和BCD的相互转换 https://blog.csd ...

  8. P2034 选择数字 / P2627 [USACO11OPEN]Mowing the Lawn G

    Link 题目描述 给定一行 \(n\) 个非负整数 \(a[1]..a[n]\) .现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入 ...

  9. 【题解】[USACO13FEB]Tractor S

    题目戳我 \(\text{Solution:}\) 好久没写啥\(dfs\)了,借这个题整理下细节. 观察到答案具有二分性,所以先求出其差的最大最小值,\(\log val\)的复杂度不成问题. 考虑 ...

  10. vue获取下拉框select的值

    1.我写的是循环遍历,然后获取id :value="v.id"这就是获取的id然后打印就可以获取id了