duoj Almost sorted interval 单调队列

来源:互联网 发布:淘宝投诉网址 编辑:程序博客网 时间:2024/05/21 09:07

听说校外打开要看人品~

http://acm.dlut.edu.cn/problem.php?id=1327

求第一个数最小,最后一个数最大的区间个数

单调队列,区间查询

q1记录作为最小的,q2记录作为最大的

cnt为i结尾有多少区间,初始值为1,注意减为0后tail2减一

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <queue>#include <cmath>#include <map>#include <vector>using namespace std;#define FOR(i, l, r) for(int i = l; i <= r; i++)#define REP(i, r, l) for(int i = r; i >= l; i--)typedef long long ll;double eps = 1e-6;const int inf = 0x3f3f3f3f;const int mod = 14997;int a[1000010];int n;int q1[1000010];int q2[1000010];int cnt[1000010];int main(){    while(~scanf("%d",&n))    {        FOR(i,1,n)            scanf("%d",&a[i]),cnt[i] =1;        int ans=1;        memset(q1,0,sizeof(q1));        memset(q2,0,sizeof(q2));        int head1=1,tail1=1;        int head2=1,tail2=1;        q1[1] = 1;        q2[1] = 1;        //r[1] = 1;        FOR(i,2,n)        {            while(head1 <= tail1 && a[q1[tail1]] > a[i]){                                cnt[q2[tail2]]--;                if(!cnt[q2[tail2]])                    tail2--;                tail1--;            }            q1[++tail1]=i;            while(head2 <= tail2 && a[q2[tail2]] <= a[i]){                cnt[i]+=cnt[q2[tail2]];                //cout<<cnt[q2[tail2]]<<endl;                tail2--;            }            q2[++tail2]=i;            ans+=cnt[i];            //cout<<ans<<endl;        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击