首页 > 其他 > 详细

ZOJ4029 Now Loading!!! (预处理+二分)

时间:2020-04-03 16:57:34      阅读:51      评论:0      收藏:0      [点我收藏+]

这道题暴力没办法做,所以要从题目式子找性质,我们发现,分母的大小最多不会超过30,而我们要求的是一个和,所以想到对分母相同的数进行前缀处理

这样求和很快,也就是说,我们进行预处理,把这些数的30个分母情况都列举一遍,而求的时候,利用二分判断分母的位置,所以在开始前先对a数组排序,就变成了一段一段求和

二分的时候一定要把左右边界想清楚,本题的左边界是0,而不是1,对于我这个二分模板来说

技术分享图片
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#define ull unsigned long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=5e5+10;
const int mod=1e9;
int sum[N];
int f[31][N];
int a[N];
int p[N];
int cnt[N];
int n,m;
void init(){
    int i,j;
    for(i=1;i<=30;i++){
        f[i][0]=0;
        for(j=1;j<=n;j++){
            f[i][j]=(f[i][j-1]+a[j]/i)%mod;
        }
    }
}
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n>>m;
        int i;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        for(i=1;i<=m;i++){
            scanf("%d",&p[i]);
        }
        sort(a+1,a+1+n);
        init();
        ll sum=0;
        for(i=1;i<=m;i++){
            ll tmp=1;
            int idx=0;
            ll ans=0;
            while(tmp*p[i]<=a[n]){
                tmp*=p[i];
                int l=0,r=n;
                while(l<r){
                    int mid=l+r+1>>1;
                    if(a[mid]<=tmp)
                        l=mid;
                    else
                        r=mid-1;
                }
                cnt[++idx]=r;
            }
            if(cnt[idx]<n){
                cnt[++idx]=n;
            }
            for(int j=1;j<=idx;j++){
                ans=(ans+f[j][cnt[j]]-f[j][cnt[j-1]]+mod)%mod;
            }
            sum=(sum+ans*i)%mod;
        }
        cout<<(sum+mod)%mod<<endl;
    }
}
View Code

 

ZOJ4029 Now Loading!!! (预处理+二分)

原文:https://www.cnblogs.com/ctyakwf/p/12627345.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!