• Eating Plan


    Eating Plan

    2019南昌G

    模数为合数,所以只有约3000个数字不为0

    记录一下不为0的数字位置

    H[x]代表距离为x的连续段的数字和的最大值

    处理出H[x]

    再H[x] = max(H[x],H[x-1])记录下前缀最大,

    对每个询问二分答案

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int n,q;
    int A[3004];
    const int mod = 998857459;
    void init()
    {
        A[0]=1;
        for(int i=1;i<=3000;i++){
            A[i]=(A[i-1]*i)%mod;
        }
    }
    int x;
    vector<int>v;
    int B[100005];
    int H[100005];
    int pre[3005];
    signed main()
    {
        init();
        scanf("%lld%lld",&n,&q);
        v.push_back(0);
        for(int i=1;i<=n;i++){
             scanf("%lld",&x);
            if(x<=3000){
                B[i]=A[x];
                v.push_back(i);
            }else{
                B[i]=0;
            }
        }
        
        for(int j=1;j<v.size();j++){
           pre[j]=(B[v[j]]+pre[j-1])%mod;
        }
        for(int i=1;i<=v.size();i++){
            for(int j=0;j+i-1<v.size();j++){
                H[v[j+i-1]-v[j]+1]=max(H[v[j+i-1]-v[j]+1],(pre[j+i-1]-pre[j-1]+mod)%mod);
            }
        }
        for(int i=1;i<=n;i++){
            H[i]=max(H[i],H[i-1]);
        }
        for(int i=1;i<=q;i++){
            scanf("%lld",&x);
            int l = 1,r =n+1;
            while(l+1<=r){
                int mid=(l+r)/2;
                if(H[mid]<x){
                    l= mid+1;
                }else r=mid;
            }
            if(l==n+1){
                cout<<-1<<'
    ';
            }else{
                cout<<l<<'
    ';
            }
        }
    }
  • 相关阅读:
    drf 三大认证详解
    管理表页面的创建
    电脑自动关机设置
    jwt 认证规则
    视图家族练习
    JQuery 数组获取和删除元素
    JQurey 添加和删除元素
    Java 占位符
    Redis
    线程
  • 原文地址:https://www.cnblogs.com/liulex/p/12015129.html
Copyright © 2020-2023  润新知