题目描述
在B进制下,数字i你有 a i a_i ai个,现要你将其组成最大的数字 X ( B ) X_{(B)} X(B)并要求它是(B-1)的倍数,且无前导零,并求出第 q i q_i qi位上的数字
思路
首先肯定是大的放前面,小的放后面
然后因为
B
k
≡
1
(
m
o
d
(
B
−
1
)
)
B^k≡1(mod\ (B - 1))
Bk≡1(mod (B−1))
所以当把所有数加起来是B-1的倍数的话
那么X就是B-1的倍数
接着,
a
i
a_i
ai加起来后不一定是B-1的倍数
所以我们就需要删数了
1.首先假如有一个321
我们再假设
s
u
m
%
(
B
−
1
)
=
3
sum\%(B-1)=3
sum%(B−1)=3(尽管不可能)
那如果我们删了3,则剩下21
如果删了12(1+2=3)则剩下3
明显21>3,所以我们要从大到小删
2.这里数只有1~B-1
而
s
u
m
%
(
B
−
1
)
sum\%(B-1)
sum%(B−1)后,只有可能时1~B-1
所以我余什么就删什么就可以了
最后我们要求第
q
i
q_i
qi位上的数
显然我们知道了每个数(1~B-1)的个数
我们做一个前缀和
就可以二分出第
q
i
q_i
qi位在哪了
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
ll n, m, tot, sum, Ques, l, r, mid, Ans;
ll A[1000250], R[1000250];
inline ll read()
{
ll x = 0, r = 1; char c = getchar();
while(c < '0' || c > '9'){if(c == '-')r = -1;c = getchar();}
while('0' <= c && c <= '9')x = x * 10 + c - 48, c = getchar();
return x * r;
}
void write(ll k)
{if(k > 9)write(k / 10); putchar(k % 10 + '0');}
void DFS(ll now, ll sh)
{
if(!(sh % (n - now)))
{
A[now] -= sh / (n - now);
return;
}
ll a = sh % (n - now);
A[now] -= sh / (n - now);
DFS(now + 1, a);
}
int main()
{
// freopen("1.txt", "r", stdin);
n = read(), Ques = read();
for(ll i = 1; i <= n; ++i)
A[n - i + 1] = read(), sum += A[n - i + 1] * (i - 1);
if(sum % (n - 1) != 0)
DFS(1, sum % (n - 1));
for(ll i = n; i >= 1; --i)
R[i] = R[i + 1] + A[i], tot += A[i];
while(Ques--)
{
m = read();
m++;
if(m > R[1])
{
printf("-1\n");
continue;
}
l = 1, r = n, Ans = -1e9;
while(l <= r)
{
mid = (l + r) >> 1;
if(R[mid] > m)l = mid + 1;
else Ans = mid, r = mid - 1;
}
if(Ans == -1e9)Ans = r;
while(R[Ans + 1] == R[Ans])Ans++;
if(R[Ans] < m)Ans--;
write(n - Ans);
putchar('\n');
}
return 0;
}