zoukankan      html  css  js  c++  java
  • 2017ACM暑期多校联合训练

    题目链接

    Problem Description
    Steph is extremely obsessed with “sequence problems” that are usually seen on magazines: Given the sequence 11, 23, 30, 35, what is the next number? Steph always finds them too easy for such a genius like himself until one day Klay comes up with a problem and ask him about it.

    Given two integer sequences {ai} and {bi} with the same length n, you are to find the next n numbers of {ai}: an+1…a2n. Just like always, there are some restrictions on an+1…a2n: for each number ai, you must choose a number bk from {bi}, and it must satisfy ai≤max{aj-j│bk≤j<i}, and any bk can’t be chosen more than once. Apparently, there are a great many possibilities, so you are required to find max{∑2nn+1ai} modulo 109+7 .

    Now Steph finds it too hard to solve the problem, please help him.

    Input
    The input contains no more than 20 test cases.
    For each test case, the first line consists of one integer n. The next line consists of n integers representing {ai}. And the third line consists of n integers representing {bi}.
    1≤n≤250000, n≤a_i≤1500000, 1≤b_i≤n.

    Output
    For each test case, print the answer on one line: max{∑2nn+1ai} modulo 109+7。

    Sample Input
    4
    8 11 8 5
    3 1 4 2

    Sample Output
    27

    Hint
    For the first sample:

    1. Choose 2 from {bi}, then a_2…a_4 are available for a_5, and you can let a_5=a_2-2=9;
    2. Choose 1 from {bi}, then a_1…a_5 are available for a_6, and you can let a_6=a_2-2=9;

    分析:

    每次需要从已有的a数组(a数组保存的就是本来的值减去下标)里面找到一个最大值,然后将这个值加入到a数组后面,接着在重复上面的过程。每次在找到一个值之后,线段树都要更新。

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #define lchild left,mid,root<<1
    #define rchild mid+1,right,root<<1|1
    #define inf 0x3f3f3f3f
    using namespace std;
    
    const int maxn = 600000;
    const int mod = 1e9+7;
    int Max[maxn<<2];
    int a[maxn];
    int b[maxn];
    
    void push_up(int root)
    {
        Max[root] = max(Max[root<<1],Max[root<<1|1]);
    }
    ///构建线段树
    void build(int left,int right,int root)
    {
        if(left == right)
        {
            Max[root] = a[left];
            return;
        }
        int mid = (left+right)>>1;
        build(lchild);
        build(rchild);
        push_up(root);
    }
    int query(int L,int R,int left,int right,int root)///[L,R]是需要查找的区间
    {
        if(L<=left && right<=R)
            return Max[root];
        int mid = (left+right)>>1;
        int ans = -inf;
        if(L<=mid) ans = max(ans,query(L,R,lchild));
        if(R>mid) ans = max(ans,query(L,R,rchild));
        return ans;
    }
    void Insert(int pos,int left,int right,int root)
    {
        if(left == right)
        {
            Max[root] = a[pos]-pos;
            return;
        }
        int mid = (left+right)>>1;
        if(pos<=mid) Insert(pos,lchild);
        else Insert(pos,rchild);
        push_up(root);
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&a[i]);
                a[i] = a[i]-i;///a数组中直接保存为它本身减去下标的值,从而每次从里面取得最大值
            }
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&b[i]);
                a[i+n] = -inf;
            }
            sort(b,b+n);
            build(1,2*n,1);///因为在从后面取的时候要从整个数组里面取包括后面的部分
            int ans = 0;
            int range = n;
            for(int i = 1; i <= n; i++)
            {
                int num = query(b[i],range,1,2*n,1);
                range++;
                a[i+n] = num;
                Insert(n+i,1,2*n,1);
                ans = (ans+num)%mod;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    02HTML和CSS知识点总结(二)
    个人对stm32ADC编程关键点的理解
    stm32_ADC定时器采样(DMA均值处理数据)
    使用AD画PCB的技能总结(纯属个人笔记,请大神多多指导)
    STM32_DAC之软件触发(Trigger)
    对stm32寄存器的理解(个人理解,大神轻喷)
    3.13考研长难句分析
    3.14考研长难句分析
    用stm32f10x建立新的工程或移植工程重要步骤
    mac air 上的Linux命令训练(1)
  • 原文地址:https://www.cnblogs.com/cmmdc/p/7246179.html
Copyright © 2011-2022 走看看