• [优先队列]HDOJ5289 Assignment


    题意:有多少个区间,区间内最大的数减去最小的数差小于k

    对每个数它所在的区间,可以只往前找(类似dp的无后效性) 比如对位置3的数,可以往前找的区间是[3, 3], [2, 3], [1, 3], [0, 3]这样

    这样 遍历a[i] 对每个a[i]往前 就可以得到所有的区间

    比如案例

    10 5

    0 3 4 5 2 1 6 7 8 9

    (最小值,最大值)的形式

    每个数增加一个(自己,自己)

    一旦不满足条件了就不必再进行下去

    那么很容易想到这是一个类似队列的情况

    对于这个案例 跑一下队列就是

     (把队中元素的个数加起来就是结果)

    那么问题就转化成了怎么知道队列中存在一个数是要弹出的(也就是上述案例6的时候,怎么知道1在队列中)

    我先用优先队列处理了一下每个数前面需要弹出的数的位置的最大值

    再用队列模拟上述过程即可

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 #define lson l, m
     5 #define rson m+1, r
     6 const int N=1e5+5;
     7 const LL mod=1e9+7;
     8 typedef pair<int, int> PI;
     9 PI a[N];
    10 int minn[N], maxn[N];
    11 void out(priority_queue<PI, vector<PI>, greater<PI> > q)
    12 {
    13     while(!q.empty())
    14     {
    15         printf("(%d %d)  ", q.top().first, q.top().second);
    16         q.pop();
    17     }
    18     puts("");
    19 }
    20 
    21 int main()
    22 {
    23 //    freopen("1002.in", "r", stdin);
    24 //    freopen("out.txt", "w", stdout);
    25     int t;
    26     scanf("%d", &t);
    27     while(t--)
    28     {
    29         int n, k;
    30         scanf("%d%d", &n, &k);
    31         for(int i=0;i<n;i++)
    32         {
    33             int x;
    34             scanf("%d", &x);
    35             a[i]=make_pair(x, i);
    36         }
    37         memset(minn, -1, sizeof(minn));
    38         memset(maxn, -1, sizeof(maxn));
    39         priority_queue<PI, vector<PI>, greater<PI> > q1;
    40         while(!q1.empty())
    41             q1.pop();
    42         q1.push(a[0]);
    43         for(int i=1;i<n;i++)
    44         {
    45             while(q1.size()>0 && a[i].first-q1.top().first>=k)
    46             {
    47                 minn[i]=max(q1.top().second, minn[i]);
    48                 q1.pop();
    49             }
    50             q1.push(a[i]);
    51 //            out(q1);
    52         }
    53         priority_queue<PI, vector<PI>, less<PI> > q2;
    54         while(!q2.empty())
    55             q2.pop();
    56         q2.push(a[0]);
    57         for(int i=1;i<n;i++)
    58         {
    59             while(q2.size()>0 && q2.top().first-a[i].first>=k)
    60             {
    61                 maxn[i]=max(q2.top().second, maxn[i]);
    62                 q2.pop();
    63             }
    64             q2.push(a[i]);
    65         }
    66 //        for(int i=0;i<n;i++)
    67 //            printf("%d %d
    ", minn[i], maxn[i]);
    68 
    69         LL ans=0;
    70         queue<int> Q;
    71         while(!Q.empty())
    72             Q.pop();
    73         int cur=0;
    74         for(int i=0;i<n;i++)
    75         {
    76             if(minn[i]<cur)
    77                 minn[i]=-1;
    78             if(maxn[i]<cur)
    79                 maxn[i]=-1;
    80             while(!Q.empty() && (maxn[i]!=-1 || minn[i]!=-1))
    81             {
    82                 if(Q.front()==maxn[i])
    83                     maxn[i]=-1;
    84                 if(Q.front()==minn[i])
    85                     minn[i]=-1;
    86                 cur=Q.front();
    87                 Q.pop();
    88             }
    89             Q.push(a[i].second);
    90             ans+=Q.size();
    91         }
    92         printf("%I64d
    ", ans);
    93     }
    94     return 0;
    95 }
    HDOJ 5289
  • 相关阅读:
    jboss:在standalone.xml中设置系统属性(system-properties)
    心得体悟帖---200608(机会都是自己创造的)
    心得体悟帖---200608(易中天评三国之刘备和诸葛亮关系启示:诚意真的重要)
    算法与数据结构---6.1、斐波那契数列-递推解法
    算法与数据结构---5、递推
    C++指针相关问题
    C++ new一个数组
    指针数组和数组指针的区别
    C++ new的用法
    webdings 和 wingdings 字体
  • 原文地址:https://www.cnblogs.com/Empress/p/4666625.html
Copyright © 2020-2023  润新知