卧薪尝胆,厚积薄发。
POI2017 Podzielno
Date: Wed Sep 05 23:06:35 CST 2018
In Category:
NoCategory
Description:
$B$
进制数,每个数字
$i$
有
$a[i]$
个。用这些数字组成一个最大的
$B$
进制数
$X$
(不能有前导零,不需要用完所有数字),使得
$X$
是
$B-1$
的倍数。
$q$
次询问,每次询问
$X$
在
$B$
进制下的第
$k$
位数字是什么。
$1\le b \le 10^6,1\le a[i]\le 10^6$
Solution:
首先可以证明
$a^k\equiv1(mod\ a-1)$
,只要不停减去
$(a-1)\times a^{k-1}$
,就能削成
$1$
,而原数是
$\begin{align}\sum_{i=0}^na[i]\times B^i=\sum_{i=0}^na[i]\end{align}$
,所以计算一下右边的式子对
$B-1$
取模,如果结果不为
$0$
,删掉对应的数字,因为不存在不删除数字的方案,而只有这一种只删除一个数字的方案,所以这样
$R$
最大,然后询问只要在前缀和数组上
$lower\_bound$
即可。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int r,q;
#define MAXR 1000010
typedef long long ll;
ll a[MAXR];
ll s[MAXR];
inline ll read()
{
register ll res = 0;
register char c = getchar();
while(!isdigit(c))c = getchar();
while(isdigit(c))
{
res = (res << 1) + (res << 3) + c - '0';
c = getchar();
}
return res;
}
int main()
{
scanf("%d%d",&r,&q);
for(register int i = 0;i < r;++i)a[i] = read();
ll sum = 0;
for(register int i = 0;i < r;++i)
sum = sum + a[i] * i;
sum = sum % ((ll)r - 1ll);
if(sum != 0)--a[sum];
s[0] = a[0];
for(register int i = 1;i < r;++i)
s[i] = s[i - 1] + a[i];
s[r] = 0x3f3f3f3f3f3f3f3f;
register ll k;
for(register int i = 1;i <= q;++i)
{
k = read();++k;
int ans = lower_bound(s + 0,s + r + 1,k) - s;
if(ans == r)puts("-1");
else printf("%d\n",ans);
}
return 0;
}
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡