1. 程式人生 > >914D Bash and a Tough Math Puzzle

914D Bash and a Tough Math Puzzle

map d+ def 查詢 div math set problem cstring

傳送門

分析

用線段樹維護區間gcd,每次查詢找到第一個不是x倍數的點,如果這之後還有gcd不能被x整除的區間則這個區間不合法

代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include
<vector> #include<set> #include<map> #include<stack> using namespace std; int d[2000100],cnt,a[500100]; inline int gcd(int x,int y){return y==0?x:gcd(y,x%y);} inline void build(int le,int ri,int wh){ if(le==ri){ d[wh]=a[le]; return; } int mid=(le+ri)>>1
; build(le,mid,wh<<1); build(mid+1,ri,wh<<1|1); d[wh]=gcd(d[wh<<1],d[wh<<1|1]); return; } inline void update(int le,int ri,int wh,int pl,int k){ if(le==ri){ d[wh]=k; return; } int mid=(le+ri)>>1; if(mid>=pl)update(le,mid,wh<<1
,pl,k); else update(mid+1,ri,wh<<1|1,pl,k); d[wh]=gcd(d[wh<<1],d[wh<<1|1]); return; } inline void q(int le,int ri,int wh,int x,int y,int k){ if(le>=x&&ri<=y){ if(d[wh]%k==0)return; if(cnt>=1){ cnt++; return; } } if(le==ri){ cnt++; return; } int mid=(le+ri)>>1; if(mid>=x)q(le,mid,wh<<1,x,y,k); if(mid<y)q(mid+1,ri,wh<<1|1,x,y,k); return; } int main(){ int n,m,i,j,k,x,y,z; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d\n",&a[i]); build(1,n,1); scanf("%d",&m); for(i=1;i<=m;i++){ scanf("%d",&k); if(k==1){ scanf("%d%d%d",&x,&y,&z); cnt=0; q(1,n,1,x,y,z); if(cnt>1)puts("NO"); else puts("YES"); }else { scanf("%d%d",&x,&y); update(1,n,1,x,y); } } return 0; }

914D Bash and a Tough Math Puzzle