題目描述:
DreamGrid has integers . DreamGrid also has queries, and each time he would like to know the value of for a given number , where , .
Input
There are multiple test cases. The first line of input is an integer indicating the number of test cases. For each test case:
The first line contains two integers and () – the number of integers and the number of queries.
The second line contains integers ().
The third line contains integers ().
It is guaranteed that neither the sum of all nor the sum of all exceeds .
Output
For each test case, output an integer , where is the answer for the -th query.
Sample Input
2
3 2
100 1000 10000
100 10
4 5
2323 223 12312 3
1232 324 2 3 5
Sample Output
11366
45619
翻譯:
輸入n和m,數組的長度爲n,第二行的n個數表示a數組,接下來輸入m個p,
對於每一個p,遍歷a數組,求得
可以得到m個這樣的數
輸出的結果:
分析:
分母的取值範圍:
每一個的範圍爲,每一個p的範圍爲,
對於分母:
int的範圍爲231-1(即2147483647)
分母的範圍可以最小爲1,31可以爲上限
枚舉每一個分母的值,對:
進行前綴和
for(int k=1; k<=30; k++)///枚舉分母
for(int i=1; i<=n; i++)
sum[i][k]=sum[i-1][k]+a[i]/k;
輸入每一個p,求的一個:
p和每一個的大小密不可分,並且有向上取整,對a數組從小到大排序,可以用二分解決
初始化兩個值 s1=p,s2=1和index=1;
從index=1枚舉分母,通過二分找到對應的區間,記錄結果,更新s1和s2
for(int i=1; i<=m; i++)
{
LL ans=0,p;
cin>>p;
LL s1=p,s2=1;
int index=1;
while(true)
{
int pos1=upper_bound(a+1,a+1+n,s1)-(a+1);///upper找到第一個大於s1的下標,減去a+1,相當於又減去1,例如 2 3 4 5 upper_bound(3)返回的是位置3,但pos1=2
int pos2=upper_bound(a+1,a+1+n,s2)-(a+1);
ans+=sum[pos1][index]-sum[pos2][index];///[pos2,pos1]這個區間的分母都爲index
index++;
s2=s1;
s1*=p;///分母爲1找完了,再找分母爲2,分母爲3,,
if(pos1==n)
break;
}
res=(res+ans*i)%mod;
}
完整代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int mod=1e9;
const int N=5*1e5+10;
int t,n,m;
LL a[N],sum[N][35];
int main()
{
cin>>t;
while (t--)
{
cin>>n>>m;
for (int i=1; i<=n; i++)
cin>>a[i];
sort(a+1,a+n+1);
for(int k=1; k<=30; k++)///枚舉分母
for(int i=1; i<=n; i++)
sum[i][k]=sum[i-1][k]+a[i]/k;
LL res=0;
for(int i=1; i<=m; i++)
{
LL ans=0,p;
cin>>p;
LL s1=p,s2=1;
int index=1;
while(true)
{
int pos1=upper_bound(a+1,a+1+n,s1)-(a+1);
int pos2=upper_bound(a+1,a+1+n,s2)-(a+1);
ans+=sum[pos1][index]-sum[pos2][index];
index++;
s2=s1;
s1*=p;
if(pos1==n)
break;
}
res=(res+ans*i)%mod;
}
cout<<res<<endl;
}
return 0;
}