G.Eating Plan

Bob is hungry now and he needs to eat some food. Alice puts nn dishes of food in front of him, numbered from 11 to nn. Alice tells him that he can only eat continuous dishes of food, or he will be poisoned by food. For example, if there are 1010 dishes, he can eat the food in the 22-nd, 33-rd and 44-th dishes but he can not eat the food in the 22-nd, 33-rd and 55-th dishes because there is the 44-th dish between them so it’s not continuous. Furthermore, if he chooses to eat food in the ii-th dish, he has to eat all food in that dish.

Bob’s stomach has a strange feature that if there is at least t~(=998857459)t (=998857459) kg food in it, the weight in it will reduce tt kg repeatedly until it is strictly lower than tt kg. Also, if the weight of food in his stomach is exactly tt kg, his stomach will be empty. Now Bob wants to eat the smallest number of dishes and remains no less than kk kg food in his stomach. Can you tell him how many dishes he needs to choose?

Input
The first line contains two integers nn and m~(1\leq n\leq 100000,1\leq m\leq 10000)m (1≤n≤100000,1≤m≤10000), indicates the number of dishes and the number of queries.

The second line contains nn integers a_1,a_2,\cdots,a_na
1

,a
2

,⋯,a
n

, which is a permutation of 1, 2, \cdots, n1,2,⋯,n, indicates that there is (a_i!)(a
i

!) kg food in the ii-th dish, where s! = 1 \times 2 \times 3 \times \cdots \times ss!=1×2×3×⋯×s.

The third line contains mm integers, the ii-th integer k_i(1\leq k_i<t)k
i

(1≤k
i

<t) indicates a query with the lower bound of weight.

Output
Each line of mm lines contains an integer indicates the number of dishes Bob needs to choose in that query. If there is no way to reach Bob’s target, output -1 instead.

样例输入复制
4 2
1 2 3 4
29 31
样例输出复制
2
3

#include <bits/stdc++.h>
#pragma GCC optimize(3 , "Ofast" , "inline")
//struct node1{ char s[N] ; char *operator [] (int x) {return s + (x) * m ;}} c;
//struct node2{int a[N] ;int *operator [] (int x) {return a + x * m ;}} s , t;
using namespace std;
typedef long long ll ;
const int INF = 0x3f3f3f3f , N = 1e5 + 10 ;
int n , m ;
const int mod = 998857459 ;
void read(int &x)
{
	x = 0 ;
	char c = getchar() ;
	while(!isdigit(c)) c = getchar() ;
	while(isdigit(c)) x = x * 10 + c - 48 , c = getchar() ;
}
ll a[N] ;
struct node
{
	ll pos , val ;
	node() {}
	node(ll pos , ll val) :pos(pos) , val(val) {} 
}b[N] ;
ll res[N] , sum[N]; 
int main()
{

    int n , m ;
	a[0] = 1; 
	for(int i = 1; i <= 2810 ;i ++)
	 a[i] = a[i - 1] * i % mod ;
	read(n) , read(m) ;
	int idx ;
	for(int i = 1; i <= n ;i ++)
	 {
	 	int x ; 
	 	scanf("%d" , &x) ;
	 	if(x <= 2802)
	 	 b[++ idx] = {i , a[x]} ;
	 }
	for(int i = 1; i <= idx ;i ++)
	  	sum[i] = (sum[i - 1] + b[i].val) % mod ;
	for(int i = 1; i <= idx ;i ++)
	 for(int j = i; j <= idx ;j ++)
	    res[b[j].pos - b[i].pos + 1] = max(res[b[j].pos - b[i].pos + 1] , ((sum[j] - sum[i - 1]) % mod + mod) % mod )  ;
	while(m --)
	{
		int x ;
		scanf("%d" , &x) ;
		int f = 0 ;
		for(int i = 1 ; i <= n ;i ++)
		 {
		 	if(res[i] >= x)
		 	 {
		 	 	cout << i << endl ;
		 	 	f = 1 ;
		 	 	break ;
			 }
		 }
		 if(!f) cout << -1 << endl ;
	} 
	return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值