2018 ccpc女生賽 口算訓練 (二分 + 唯一分解定理)
阿新 • • 發佈:2019-01-25
小Q非常喜歡數學,但是他的口算能力非常弱。因此他找到了小T,給了小T一個長度為nn的正整數序列a1,a2,...,ana1,a2,...,an,要求小T丟擲mm個問題以訓練他的口算能力。
每個問題給出三個正整數l,r,dl,r,d,小Q需要通過口算快速判斷al×al+1×...×ar−1×aral×al+1×...×ar−1×ar是不是dd的倍數。
小Q迅速地回答了出來,但是小T並不知道正確答案是什麼,請寫一個程式幫助小T計算這些問題的正確答案。Input第一行包含一個正整數T(1≤T≤10)T(1≤T≤10),表示測試資料的組數。
每組資料第一行包含兩個正整數n,m(1≤n,m≤100000)n,m(1≤n,m≤100000),分別表示序列長度以及問題個數。
第二行包含nn個正整數a1,a2 ,...,an(1≤ai≤100000)a1,a2,...,an(1≤ai≤100000),表示序列中的每個數。
接下來mm行,每行三個正整數l,r,d(1≤l≤r≤n,1≤d≤100000)l,r,d(1≤l≤r≤n,1≤d≤100000),表示每個問題。Output對於每個問題輸出一行,若是倍數,輸出Yes,否則輸出No。Sample Input
每個問題給出三個正整數l,r,dl,r,d,小Q需要通過口算快速判斷al×al+1×...×ar−1×aral×al+1×...×ar−1×ar是不是dd的倍數。
小Q迅速地回答了出來,但是小T並不知道正確答案是什麼,請寫一個程式幫助小T計算這些問題的正確答案。Input第一行包含一個正整數T(1≤T≤10)T(1≤T≤10),表示測試資料的組數。
每組資料第一行包含兩個正整數n,m(1≤n,m≤100000)n,m(1≤n,m≤100000),分別表示序列長度以及問題個數。
第二行包含nn個正整數a1,a2
接下來mm行,每行三個正整數l,r,d(1≤l≤r≤n,1≤d≤100000)l,r,d(1≤l≤r≤n,1≤d≤100000),表示每個問題。Output對於每個問題輸出一行,若是倍數,輸出Yes,否則輸出No。Sample Input
1 5 4 6 4 7 2 5 1 2 24 1 3 18 2 5 17 3 5 35Sample Output
Yes No No Yes
先用vector記錄下每個因子出現的位置。vector裡存的是含有i這個因子的下標。
查詢l到r裡因子個數時用upper_bound() - lower_bound()就可以。
#include<bits/stdc++.h> using namespace std; vector<int> a[100005]; int T, n, m; void init(int x, int Index){ for(int i = 2; i * i <= x; i++){ if(x % i == 0){ while(x % i == 0){ x /= i; a[i].push_back(Index); } } } if(x > 1) a[x].push_back(Index); } int query(int l, int r, int x){ return upper_bound(a[x].begin(), a[x].end(), r) - lower_bound(a[x].begin(), a[x].end(), l); } int judge(int l, int r, int x){ for(int i = 2; i * i <= x; i++){ if(x % i == 0){ int t = 0; while(x % i == 0){ x /= i; t++; } int c = query(l, r, i); if(t > c) return 0; } } if(x > 1 && query(l, r, x) < 1) return 0; return 1; } int main() { scanf("%d", &T); while(T--){ for(int i = 0; i < 100005; i++) a[i].clear(); scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++){ int x; scanf("%d", &x); init(x, i); } for(int i = 0; i < m; i++){ int l, r, d; scanf("%d%d%d", &l, &r, &d); int flag = judge(l, r, d); if(flag) printf("Yes\n"); else printf("No\n"); } } return 0; }