ZOJ-4029 Now Loading!!!

题干:

给你n个ai和m个pi,求 ∑ i = 1 m \sum_{i=1}^{m} i=1m(i* ∑ j = 1 n \sum_{j=1}^{n} j=1n ⌊ a j ⌈ log ⁡ p i a j ⌉ ⌋ \lfloor \frac{a_j}{\lceil \log_{p_i}{a_j} \rceil} \rfloor logpiajaj) % 1 0 9 10^9 109的值。
2 ≤ p i ≤ 1 0 9 2 \le p_i \le 10^{9} 2pi109
2 ≤ a i ≤ 1 0 9 2 \le a_i \le 10^{9} 2ai109

思路:

观察 ⌊ log ⁡ p i a j ⌋ \lfloor \log_{p_i}^{a_j}\rfloor logpiaj
a i a_i ai= 1 0 9 10^{9} 109 p i p_i pi=2时取最大值30
p i p_i pi= 1 0 9 10^{9} 109 a i a_i ai=2时取最小值1
又因为是取整,所以分母的范围在[1,30]之间,然后我们可以将分母相同的数放到一起计算,先将 a i a_i ai按从小到大排序,我们就可以用二维数组c[i][j]表示分母为i的分子为 a j a_j aj的前缀和,
我们对于每次输入 p i p_i pi,按 p i k p_i ^ k pik求出在a[]数组中的上界 p o s i pos_i posi,则 ∑ j = 1 n \sum_{j=1}^{n} j=1n ⌊ a j ⌈ log ⁡ p i a j ⌉ ⌋ \lfloor \frac{a_j}{\lceil \log_{p_i}{a_j} \rceil} \rfloor logpiajaj就变成了求 ∑ j = 1 n \sum_{j=1}^{n} j=1nc[k][ p o s i pos_i posi](也就是根据分母求不同的前缀和)
注意段错误,前缀和数组(直接用vector最好)、中途的求和、最后的答案用long long型, a i a_i ai数组和其他的用int

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
const ll mod = 1e9;
int x[200000];
ll c[35][200000]; 
int main()
{
	int t,n,m;
	ll a;
	while(scanf("%d",&t)!=EOF)
	{
		while(t--)
		{
			scanf("%d%d",&n,&m);
			for(int i=1;i<=n;i++){
				scanf("%d",&x[i]);
			}
			sort(x+1,x+n+1);
			for(int i=1;i<=30;i++){
				c[i][0]=0;
				for(int j=1;j<=n;j++){
					c[i][j]=c[i][j-1]+x[j]/i;
				}
			}
			ll ans=0;
			for(int i=1;i<=m;i++){
				scanf("%lld",&a);
				ll  b=a,now=0;
				int last=0,t=0;
	            while(b/a<=x[n])
	            {
	                t++;
	                int pos=upper_bound(x+1,x+1+n,b)-(x+1);
	                now+=(c[t][pos]-c[t][last]+mod)%mod; 
					last=pos;
	                if(b<x[n]) 
						b*=a; 
					else 
						break;
	            }
	            ans=(ans+now%mod*i%mod)%mod;
			}
			printf("%lld\n",ans);
		}
	}
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值