博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2017多校联合二1003(hdu6047)Maximum Sequence
阅读量:4204 次
发布时间:2019-05-26

本文共 4486 字,大约阅读时间需要 14 分钟。

预处理:a_i -= i ,易证明从最小的b开始选每次选最大的一定可以使结果最大。 证明思路:如果条件改为a_i<=max{a_j-j|b_k<=j<=n},那么b的顺序与最后的结果无关。条件改回来后,由于每次要计算一个数的最大值时都有a_(n+1)...a_(i-1)在范围中,所以每次只需让a_i - i尽可能大,那么就把大的数尽早用上,每次一定考虑尽量多的数字,这样取得的数字就尽可能的大。 所以说每次就是求区间最值,加在答案上。由于贪心的思路,每次要求的区间的下界是单调不降的,故可以用单调队列优化到O(n)的复杂度。 由于1 ≤ b_i ≤ n,对b排序可以用哈希排序(桶排序)完成。 进一步观察,可以发现这样贪心时 a_(n+1)...a_i 其实是单调不增的,所以并不需要每次求区间最值了,选第一个数时就选最大的,后面的选择顺序与最终结果无关了。

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define lowbit(x) (x&-x)#define e exp(1.0)//ios::sync_with_stdio(false);// auto start = clock();// cout << (clock() - start) / (double)CLOCKS_PER_SEC;typedef long long ll;typedef long long LL;using namespace std;const int maxn=250005;const int mod=1e9+7;int n;struct node{ int id,value;};int a[maxn];vector
b;int num[maxn];deque
que;ll ans;int main(){ while(cin>>n) { ans=0; memset(num,0,sizeof(num)); memset(a,0,sizeof(a)); que.clear(); b.clear(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int x; for(int i=1;i<=n;i++) { scanf("%d",&x); num[x]++; } for(int i=1;i<=n;i++) for(int j=1;j<=num[i];j++) b.push_back(i); for(int i=1;i<=n;i++) { while(!que.empty() && que.back().value<=a[i]-i) que.pop_back(); que.push_back({i,a[i]-i}); } for(int i=1;i<=n;i++) { while(que.front().id

#include <iostream>

#include <algorithm>

#include <cstdio>

#include <cmath>

#include <cstring>

#include <string>

#include <string.h>

#include <map>

#include <set>

#include <queue>

#include <deque>

#include <list>

#include <bitset>

#include <stack>

#include <stdlib.h>

#define lowbit(x) (x&-x)

#define e exp(1.0)

//ios::sync_with_stdio(false);

//    auto start = clock();

//    cout << (clock() - start) / (double)CLOCKS_PER_SEC;

typedef long long ll;

typedef long long LL;

using namespace std;

const int maxn=250005;

const int mod=1e9+7;

int n;

struct node

{

    int id,value;

};

int a[maxn];

vector<int>b;

int num[maxn];

deque<node>que;

ll ans;

int main()

{

    while(cin>>n)

    {

        ans=0;

        memset(num,0,sizeof(num));

        memset(a,0,sizeof(a));

        que.clear();

        b.clear();

        for(int i=1;i<=n;i++)

            scanf("%d",&a[i]);

        int x;

        for(int i=1;i<=n;i++)

        {

            scanf("%d",&x);

            num[x]++;

        }

        for(int i=1;i<=n;i++)

            for(int j=1;j<=num[i];j++)

                b.push_back(i);

        for(int i=1;i<=n;i++)

        {

            while(!que.empty() && que.back().value<=a[i]-i)

                que.pop_back();

            que.push_back({i,a[i]-i});

        }

        for(int i=1;i<=n;i++)

        {

            while(que.front().id<b[i-1])

                que.pop_front();

            int t=que.front().value;

            ans=(ans+t)%mod;

            t=max(t-n-i,0);

            while(que.back().value<=t)

                que.pop_back();

            que.push_back({n+i,t});

        }

        cout<<ans<<endl;

    }

    return 0;

}

另解:

//优先队列

[cpp]   
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<cmath>  
  5. #include<string>  
  6. #include<algorithm>  
  7. #include<queue>  
  8. #include<stack>  
  9. #include<set>  
  10. #include<map>  
  11. #include<vector>  
  12. using namespace std;  
  13. typedef long long ll;  
  14. const int maxn = 250010;  
  15. const int mod = 1e9+7;  
  16. int n;  
  17. int a[maxn];  
  18. int b[maxn];  
  19. struct Node{  
  20.     int val;  
  21.     int id;  
  22.     friend bool operator < ( const Node &a, const Node &b)  
  23.     {  
  24.         if( a.val != b.val)  
  25.             return a.val < b.val;  
  26.         return a.id > b.id;  
  27.     }  
  28. };  
  29. priority_queue<Node> q;  
  30.   
  31. int main()  
  32. {  
  33.     while( ~scanf("%d",&n))  
  34.     {  
  35.         while( !q.empty())  
  36.             q.pop();  
  37.         Node tmp;  
  38.         forint i = 1; i <= n; i++)  
  39.         {  
  40.             scanf("%d",&a[i]);  
  41.             tmp.id = i;  
  42.             tmp.val = a[i]-i;  
  43.             q.push(tmp);  
  44.         }  
  45.         forint i = 1; i <= n; i++)  
  46.             scanf("%d",&b[i]);  
  47.         sort(b+1,b+1+n);  
  48.         ll ans = 0;  
  49.         int p = 1;  
  50.         while( p <= n)  
  51.         {  
  52.             tmp = q.top();  
  53.             while( b[p] > tmp.id)  
  54.             {  
  55.                 q.pop();  
  56.                 tmp = q.top();  
  57.             }  
  58.             ans=(ans+tmp.val)%mod;  
  59.             tmp.val -= (n+p);  
  60.             tmp.id = n+p;  
  61.             q.push(tmp);  
  62.             p++;  
  63.         }  
  64.         printf("%lld\n",ans);  
  65.     }  
  66.     return 0;  
  67. }  

//单调队列

[cpp]   
  1. #include<cstdio>  
  2. #include<cmath>  
  3. #include<cstring>  
  4. #include<algorithm>  
  5. #include<iostream>  
  6.   
  7. using namespace std;  
  8. #define LL long long  
  9. const int mod = 1e9+7;  
  10. const int maxn = 250010;  
  11. int n;  
  12. int a[maxn];  
  13. int b[maxn];  
  14. struct Node{  
  15.     int id;  
  16.     int val;  
  17. };  
  18. Node q[maxn<<1];  
  19.   
  20. int main()  
  21. {  
  22.     while( ~scanf("%d",&n))  
  23.     {  
  24.         int head = 0;  
  25.         int tail = 0;  
  26.         forint i = 1; i <= n; i++)  
  27.         {  
  28.             scanf("%d",&a[i]);  
  29.             if( tail == 0)  
  30.             {  
  31.                 q[tail].id = i;  
  32.                 q[tail++].val = a[i]-i;  
  33.             }  
  34.             else  
  35.             {  
  36.                 while( head < tail && a[i]-i >= q[tail-1].val)  
  37.                     tail--;  
  38.                 q[tail].id = i;  
  39.                 q[tail++].val = a[i]-i;  
  40.             }  
  41.         }  
  42.         forint i = 1; i <= n; i++)  
  43.             scanf("%d",&b[i]);  
  44.         sort(b+1,b+1+n);  
  45.   
  46.         int p = 1;  
  47.         Node tmp;  
  48.         LL ans = 0;  
  49.         while( p <= n)  
  50.         {  
  51.             while( b[p] > q[head].id)  
  52.                 head++;  
  53.             ans = (ans+q[head].val)%mod;  
  54.             tmp.id = p+n;  
  55.             tmp.val = q[head].val-(n+p);  
  56.             while( head < tail && tmp.val >= q[tail-1].val)  
  57.                 tail--;  
  58.             q[tail++] = tmp;  
  59.             p++;  
  60.         }  
  61.         printf("%lld\n",ans);  
  62.   
  63.     }  
  64.   
  65.     return 0;  
  66. }  

转载地址:http://xlali.baihongyu.com/

你可能感兴趣的文章
spring-cloud-eureka
查看>>
springcloud采坑-jason序列化中的Date对象
查看>>
JDK-SPI简介【一】
查看>>
spring cloud采坑列表
查看>>
mochiweb——初始化
查看>>
Erlang进程池(整理)
查看>>
REDIS源代码分析 – PROTOCOL(笔记+补充)
查看>>
正则表达式
查看>>
参照《第一行代码》开发CoolWeather (一)
查看>>
Android ImageView用法
查看>>
纯CSS实现3D旋转
查看>>
CSS实现图片轮播
查看>>
Spring 事务管理
查看>>
hql 语法与详细解释
查看>>
Spring集成mybatis后,打印SQL语句
查看>>
DRUID连接池的实用 配置详解
查看>>
设计模式Design Patterns (一)
查看>>
Linux安装apache源码包报错:Cannot use an external APR with the bundled APR-util
查看>>
Linux安装apache源码包报错:mod_deflate has been requested but can not be built due to prerequisite failures
查看>>
Linux 下 apache启动、停止、重启命令
查看>>