【模拟赛】荒地群猎

题目描述

在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)) Bk1(mod (B1))
所以当把所有数加起来是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%(B1)=3(尽管不可能)
那如果我们删了3,则剩下21
如果删了12(1+2=3)则剩下3
明显21>3,所以我们要从大到小删
2.这里数只有1~B-1
s u m % ( B − 1 ) sum\%(B-1) sum%(B1)后,只有可能时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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值