问题 B: Podzielno
时间限制: 1 Sec 内存限制: 128 MB提交: 97 解决: 31
[提交] [状态] [讨论版] [命题人:admin]
题目描述
输入
第二行包含B个正整数a[0],a[1],a[2],...,a[B-1](1<=a[i]<=10^6)。
接下来q行,每行一个整数k(0<=k<=10^18),表示一个询问。
输出
样例输入
复制样例数据
3 3
1 1 1
0
1
2
样例输出
0
2
-1
问题
中文题意 不做解释
分析
有一个结论,就是一个数能被B-1整除当且仅当这个数在B进制下的每一位的和能被B-1整除。
证明:
当一个数的某一位+1时,若进位,则这一位要减去B-1,下一位要+1,则总的贡献是+1.
当一个数的某一位-1时,若退位,则这一位要加上B-1,下一位要-1,则总的贡献是-1.
于是当一个数加上B-1时,它在B进制下每一位的总和对B-1取模的值是不变的。
要是B-1的倍数,那么各位之和对B-1取余一定是零。
a*Bk≡a (mod (B-1) )
因为要求最大的B进制数,所以贪心每个数都占一位,对B-1取余,减去一个余数。
所以求一个前缀和,lower_bound求值就可以了。


/// author:Kissheart /// #include<stdio.h> #include<algorithm> #include<iostream> #include<string.h> #include<vector> #include<stdlib.h> #include<math.h> #include<queue> #include<deque> #include<ctype.h> #include<map> #include<set> #include<stack> #include<string> #define INF 0x3f3f3f3f #define FAST_IO ios::sync_with_stdio(false) const double PI = acos(-1.0); const double eps = 1e-6; const int MAX=1e6+10; const int mod=1e9+7; typedef long long ll; using namespace std; #define gcd(a,b) __gcd(a,b) inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;} inline ll inv1(ll b){return qpow(b,mod-2);} inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;} inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;} //freopen( "in.txt" , "r" , stdin ); //freopen( "data.txt" , "w" , stdout ); ll B,k,q; ll a[MAX],sum[MAX]; ll s,p; int main() {scanf("%lld%lld",&B,&q);p=B-1;for(ll i=0;i<B;i++){scanf("%lld",&a[i]);s=(s+i*a[i])%p;}if(s) a[s]--;sum[0]=a[0];for(ll i=1;i<B;i++) sum[i]=sum[i-1]+a[i];while(q--){scanf("%lld",&k);if(k+1>sum[B-1])printf("-1\n");else{ll pos;pos=lower_bound(sum,sum+B,k+1)-sum;printf("%lld\n",pos);}}return 0; }