GCD Matrix
Alex has two arrays defined as and . He created an matrix, , where for each in . Recall that is the greatest common divisor of and .
For example, if and , he builds like so:
Alex's friend Kiara loves matrices, so he gives her questions about matrix where each question is in the form of some submatrix of with its upper-left corner at and its bottom-right corner at . For each question, find and print the number of distinct integers in the given submatrix on a new line.
Input Format
The first line contains three space-separated integers describing the respective values of (the size of array ), (the size of array ), and (Alex's number of questions).
The second line contains space-separated integers describing .
The third line contains space-separated integers describing .
Each line of the subsequent lines contains four space-separated integers describing the respective values of , , , and for the question (i.e., defining a submatrix with upper-left corner and bottom-right corner ).
Constraints
Scoring
- for of score.
- for of score.
Output Format
For each of Alex's questions, print the number of distinct integers in the given submatrix on a new line.
Sample Input 0
3 3 3
1 2 3
2 4 6
0 0 1 1
0 0 2 2
1 1 2 2
Sample Output 0
2
3
3
Explanation 0
Given and , we build the following :
The diagram below depicts the submatrices for each of the questions in green:
- For the submatrix between and , the set of integers is . The number of distinct integers is .
- For the submatrix between and , the set of integers is . The number of distinct integers is .
- For the submatrix between and , the set of integers is . The number of distinct integers is .
题目链接:https://www.hackerrank.com/contests/hourrank-17/challenges/gcd-matrix
题目的题意我就不说了,很简单,标神今天上午给我们抓的比赛题之一,已经快被标神整疯了,这个题我一开始想到预处理,但是接着让我给否了,存不开。。。然后想到了莫比乌斯反演,但是小推一下发现并不是反演,最后什么也没用给过了,这个题我用了唯一分解定理和反演的思想,具体的题解看标神的吧,我就不写了。
http://blog.csdn.net/huayunhualuo/article/details/54944548
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN=1e5+7;
const int MIX=1e5;
int a[MAXN];
int b[MAXN];
long long xin[MAXN];
long long numa[MAXN];
long long numb[MAXN];
int main(){
int n1,n2,m;
while(~scanf("%d%d%d",&n1,&n2,&m)){
for(int i=0;i<n1;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n2;i++){
scanf("%d",&b[i]);
}
int cnt;
while(m--){
cnt=0;
int x1,y1,x2,y2,j;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
memset(numa,0,sizeof(numa));
memset(numb,0,sizeof(numb));
for(int i=x1;i<=x2;i++)
numa[a[i]]++;
for(int i=y1;i<=y2;i++)
numb[b[i]]++;
for(int i=1;i<=MIX;i++){
j=i<<1;
while(j<=MIX){
numa[i]+=numa[j];
numb[i]+=numb[j];
j+=i;
}
}
for(int i=MIX;i>=1;i--){
xin[i]=numa[i]*numb[i];
j=i<<1;
while(j<=MIX){
xin[i]-=xin[j];
j+=i;
}
if(xin[i]){
cnt++;
}
}
printf("%d\n",cnt);
}
}
return 0;
}