日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ5358: [Lydsy1805月赛]口算训练

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ5358: [Lydsy1805月赛]口算训练 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題解:判斷d是否整除,可以轉化為求這段區間內d的因子的指數是否均大于d中的指數。容易想到把每個數字都分解為素因子形式,對每個素數出現的次數求個前綴和即可。然而,這樣時間空間都不行。注意到對于一個數x,小于sqrt(x)的素因子最多sqrt(x)個,而每個數包含大于sqrt(x)的素因子最多一個。那么容易想到,對于小于sqrt(x)的素因子預處理指數項前綴和。大于sqrt(n)的數,提前分離出來,只需實現區間查詢一個數是否出現即可。這個操作,直接分塊預處理一下就好了。復雜度o(n×sqrt(n))(大概一輩子都是簽到選手了吧。

#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <set> #define mem(MW) memset(MW,0,sizeof(MW)) #define rep(i,a,b) for(int i=a;i<=b;++i) typedef long long ll; const int N = 1e5 + 100; const int lim = 320; inline int read() {char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f; } using namespace std; int n, m, a[N]; int p[N], notp[N], nxt[N]; void init() {notp[1]=1;nxt[1]=1;rep(i,2,1e5) {if(!notp[i])p[++p[0]]=i,nxt[i]=i;rep(j,1,p[0]) {if(p[j]*i>1e5)break;notp[p[j]*i]=1;nxt[p[j]*i]=p[j];if(i%p[j]==0)break;}} } int b[lim+3][N], v[N], cnt, c[N], sum[N], sumc[N]; void cal_pr(int x) {cnt=0;while(x!=1) {int t=nxt[x];v[++cnt]=t; sum[t]=0;while(x%t==0)x/=t,++sum[t];} } int belong[N], l[lim+3], r[lim+3], B, num, S[lim+3][N]; void build() {mem(sumc), mem(b), mem(S);B=sqrt(n);num=n/B;if(n%B)++num;rep(i,1,n)belong[i]=(i-1)/B+1;rep(i,1,num)l[i]=(i-1)*B+1,r[i]=i*B;r[num]=n;rep(i,1,n) {cal_pr(a[i]);rep(j,1,cnt) {if(v[j]<lim) b[v[j]][i]+=sum[v[j]];else S[belong[i]][v[j]]+=sum[v[j]];}c[i]=v[cnt];sumc[i]=sum[v[cnt]];}rep(j,1,lim)rep(i,2,n) b[j][i]+=b[j][i-1]; } int fd(int L, int R, int x) {int tmp=0;if(R-L+1<=B) {rep(i,L,R) if(c[i]==x) tmp+=sumc[i];return tmp>=sum[x];}rep(i,L,r[belong[L]]) if(c[i]==x) tmp+=sumc[i];rep(i,belong[L]+1,belong[R]-1) tmp+=S[i][x];rep(i,l[belong[R]],R) if(c[i]==x) tmp+=sumc[i];return tmp>=sum[x]; } int ck(int l, int r, int d) {int tmp=-1;cal_pr(d);rep(i,1,cnt) {if(v[i]<lim&&b[v[i]][r]-b[v[i]][l-1]<sum[v[i]]) return 0;if(v[i]>=lim) tmp=v[i];}if(tmp==-1) return 1;return fd(l,r,tmp); } int main() {int T;init();T=read();while(T--) {n=read(), m=read();rep(i,1,n) a[i]=read();build();rep(i,1,m) {int l,r,d;l=read(), r=read(), d=read();if(ck(l,r,d)) puts("Yes");else puts("No");}}return 0; }

?

轉載于:https://www.cnblogs.com/RRRR-wys/p/9099627.html

總結

以上是生活随笔為你收集整理的BZOJ5358: [Lydsy1805月赛]口算训练的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。