HDU 6287 口算訓練

2021-08-20 10:20:44 字數 2509 閱讀 9824

小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 ...