HDOJ 6047-Maximum Sequence

来源:互联网 发布:淘宝网玉手镯 编辑:程序博客网 时间:2024/06/02 04:58

Maximum Sequence

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 159    Accepted Submission(s): 79


题目链接:点击打开链接



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+1a2n. Just like always, there are some restrictions on an+1a2n: 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;
 

题意:给你一个数n,然后给你两个序列,a序列和b序列,每个序列都有n个数,它们的取值范围是1≤n≤250000, n≤a_i≤1500000, 1≤b_i≤n.然后让你找到a序列的an+1到a2n,并求出an+1到a2n的求和最大值,即max{2nn+1ai},对每个ai找最优解的条件限制为ai≤max{aj-j│bk≤j<i}。思路写在代码的注释上,试着理解。

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;const int Mod = 1e9 + 7;int a[3000020];int b[250005];int c[230005];int main(){    long long int n;    int haha=0;    while(~scanf("%lld",&n))    {        long long int ans=0,sum=0;        haha++;//最多20组测试数据,再多就跳出        if(haha>20)            break;        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        for(int i=1;i<=n;i++)            scanf("%d",&b[i]);        sort(b+1,b+n+1);//对b进行排序,从小到大        for(int i=n;i>0;i--)        {//重新用一个数组存a数组里的数减去对应的下标。        //注意是从右往左存,并且如果左边的计算数值小于右边,则用右边值替代        //原因是后面的遍历是从b数组里最小的数开始作为下标判断的        //这样代替不影响ai的取值,并且可以快速的取到区间最大值            if(a[i]-i>=ans)                ans=a[i]-i;            c[i]=ans;        }        int maxx=-1;//先将最大值初始化为符合题意的最小值        for(int i=1;i<=n;i++)        {            if(c[b[i]]>maxx)//如果区间最大值大于最大值,则让ai等于区间最大值                a[n+i]=c[b[i]];            else//否则则等于最大值。                a[n+i]=maxx;            if(a[n+i]-n-i>maxx)//maxx的作用出来了            //其实maxx它就是为了记录新得到的数减去对应下标得到的新值                //万一比之前区间最大值大,那么就得记录                maxx=a[n+i]-n-i;            sum+=a[n+i];//然后开始求和            if(sum>=Mod)//如果超过了10^9+7,则要对该数取余                sum%=Mod;        }        printf("%lld\n",sum);    }    return 0;}


 

原创粉丝点击