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; }