小q非常喜歡數學,但是他的口算能力非常弱。因此他找到了小t,給了小t乙個長度為n的正整數序列a1,a2,…,an,要求小t丟擲m個問題以訓練他的口算能力。
每個問題給出三個正整數l,r,d小q需要通過口算快速判斷al
×al+
1×..
.×ar
−1×a
r al×
al+1
×...
×ar−
1×ar
是不是d的倍數。
小q迅速地回答了出來,但是小t並不知道正確答案是什麼,請寫乙個程式幫助小t計算這些問題的正確答案。
第一行包含乙個正整數t(1≤t≤10),表示測試資料的組數。
每組資料第一行包含兩個正整數n,m(1≤n,m≤100000),分別表示序列長度以及問題個數。
第二行包含n個正整數a1,a2,…,an(1≤ai≤100000),表示序列中的每個數。
接下來m行,每行三個正整數l,r,d(1≤l≤r≤n,1≤d≤100000),表示每個問題。
對於每個問題輸出一行,若是倍數,輸出yes,否則輸出no。
1
5 46 4 7 2 5
1 2 24
1 3 18
2 5 17
3 5 35
yes
nono
yes
考慮到資料範圍為1e5 質數大約有1e4個
判斷乙個區間的乘積是否為乙個數d的倍數
判斷方法是對d進行質因子分解,現在我們只關注這些素數
對於乙個素數,看對於詢問區間[l
,r] [l,
r]
中能整除這個素數幾次(也就是區間內每個數質因子分解,若有這個素數則就是對應的指數(相加),若沒有就為0
現在的問題是怎麼維護m次詢問的結果
你會發現1e5個數就1e
5log
(1e5
) 1e5
log(
1e5)
個素數,只有這些值對答案有貢獻,所以理論上是可以存下的。
而且只用關注1e4個素數
於是我們用二維vectorvec[1e4]
對於每一維,存的是有該質因子的每個數(共1e5個)的權值 即對應指數 並維護字首和vector pre[1e4]
所以對於每個n(1e5),在詢問前預處理上述兩個陣列時間n
logn
n lo
gn
對於乙個詢問l,r,d
對d質因子分解後(可以提前預處理,也可以)o
(n−−
√)) o(
n)
直接做然後對於每個質數,找到對應的vec[prime] 二分l,r 直接用字首和得到指數
看是否能整除即可
若所有d的質因子都能整除
則yes 否則no
時間複雜度t∗
mlog
nlog
n t∗m
logn
logn
注意二分細節 upper_bound 後-1 不然非法訪問未知記憶體
以及維護pre 先 push佔位資料0 方便pre
#include
using
namespace
std;
typedef
long
long ll;
int debug_num=0;
#define debug cout<<"debug "<<++debug_num<<" :"
const
int maxn=1e5+10;
int no[maxn];
int n,m;
vector
ans[maxn];//質因子
vector
bns[maxn];//對應指數
vector
vec[maxn];
vector
pre[maxn];
//先預處理每個數有哪些質因數
void init1(int n)//處理1000005個數本機跑了1.303s 評測機0.4s左右}}
}void init2(int n)}}
}void init()
for(int i=0;i<=maxn;++i)
for(int i=1;i<=n;++i)
}}bool check(int l,int r,int d,int id)//有了d和id就知道當前質數和指數
int main()
init();
// for(int i=2;i<=30;++i)
// cout// }
for(int i=1;i<=m;++i)
}if(flag) cout
<<"yes"
cout
<<"no"
0;}
HDU 6287 口算訓練
小q非常喜歡數學,但是他的口算能力非常弱。因此他找到了小t,給了小t乙個長度為n的正整數序列a1,a2,an,要求小t丟擲m個問題以訓練他的口算能力。每個問題給出三個正整數l,r,d,小q需要通過口算快速判斷al al 1 ar 1 ar是不是d的倍數。小q迅速地回答了出來,但是小t並不知道正確答案...
hdu 6287 口算訓練
題意 小q非常喜歡數學,但是他的口算能力非常弱。因此他找到了小t,給了小t乙個長度為n n n的正整數序列a1,a2,a n a1,a2,an a1,a2,an,要求小t丟擲m m m個問題以訓練他的口算能力。每個問題給出三個正整數l,r d l,r,d l,r,d,小q需要通過口算快速判斷al a...
HDU6287 口算訓練(莫隊演算法)
小q非常喜歡數學,但是他的口算能力非常弱。因此他找到了小t,給了小t乙個長度為 nn 的正整數序列 a1 a2,ana1,a2,an 要求小t丟擲 mm 個問題以訓練他的口算能力。每個問題給出三個正整數 l,r,dl,r,d 小q需要通過口算快速判斷 al al 1 ar 1 a ral al 1 ...