Bzoj4724--Poi2017Podzielno

题意 : 

给你0 ~ B-1每个数的个数a[i],让你组成一个最大的B进制数 X 使X mod B-1 = 0 ,q个询问每次询问X的第k位数是什么。

--------------------------------------此后一千里--------------------------------------------------------

可以很简单观察出满足条件的X各位和一定是B-1的倍数。简单证明 : 设 (X = x0+x1*B+x2*B^2+...+xn*B^n) mod B-1 = 0

即 (x0 % p + x1*B % p + x2*B^2 % p +.....) % p = 0 ,因为B % B-1 = 1,所以 x0 + x1 + x2 + ... + xn % p = 0

因为题目条件a[i] > 0 所以我们总可以有 sigma(a[i])- 1 个 数的合法解,显然这个解是最优解。询问就直接二分一下回答。

代码 : 

#include<bits/stdc++.h>
#define LL long long
using namespace std;

inline int Max(int a,int b) {return a>b?a:b;}
inline int Min(int a,int b) {return a<b?a:b;}
inline int Abs(int a) {return a>0?a:-a;}
inline int Sqr(int a) {return a*a;}

#define MAXN 1000006

int B,q;LL a[MAXN],sum,b[MAXN],k,all;

int BS(LL k) {
    int l=0,r=B-1,mid,ret;
    while(l<=r) {
        mid=l+r>>1;
        if(b[mid]>=k) r=mid-1,ret=mid;
        else l=mid+1;
    }
    return ret;
}

int main() {
    scanf("%d%d",&B,&q);
    for(int i=0;i<B;i++) {scanf("%lld",&a[i]);sum=(sum+i*a[i])%(B-1);all+=a[i];}
    if(sum) a[sum]--,all--;b[0]=a[0];
    for(int i=1;i<B;i++) b[i]=b[i-1]+a[i];
    for(int i=1;i<=q;i++) {
        scanf("%lld",&k);k++;
        if(k>all) puts("-1");
        else printf("%d
",BS(k));
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ihopenot/p/6498128.html