BZOJ 4724: [POI2017]Podzielno

Description

由\([0,B-1]\)的数字构造一个 \(B\) 进制数字,使得他是 \(B-1\) 的倍数.

Sol

贪心+二分.

首先 \(X\) 是 \(B-1\) 的倍数,那么有 \(X \equiv 0 (mod B-1)\)

设 \(X\) 的第 \(i\) 位,为\(X_i\)

那么则有 \(\sum_{i=0}^{n-1}x_iB^i \equiv 0(mod B-1)\)

因为 \(B^i \equiv 1(mod B-1)\)

所以就是 \(\sum_{i=0}^{n-1}x_i \equiv 0(mod B-1)\)

数据保证了 \(a_i \geqslant 1\)

所以直接去掉这一位就可以了...

询问直接二分.

PS:一开始一直在想将 \(X\) 表示成 \(tB-t\) 的形式...就是在末尾加个 \(0\) 减去 \(t\),计算每一位的贡献...后来失败了... 

Code

/**************************************************************
    Problem: 4724
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:2740 ms
    Memory:9104 kb
****************************************************************/
 
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
 
typedef long long LL;
const int N = 1000005;
 
LL n,t,m,p;
LL a[N];
 
inline LL in(LL x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
    while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; }
int main(){
    n=in(),t=in();m=n-1;
    for(int i=0;i<n;i++) a[i]=in(),p=(p+(i*a[i]%m))%m;
    if(p) a[p]--;
    for(int i=1;i<n;i++) a[i]+=a[i-1];
    for(LL k,ans;t--;){
        k=in();ans=upper_bound(a,a+n,k)-a;
        if(ans>m) puts("-1");else printf("%lld\n",ans);
    }return 0;
}

  

 

posted @ 2016-12-05 19:30  北北北北屿  阅读(147)  评论(0编辑  收藏  举报