zoukankan      html  css  js  c++  java
  • 模拟赛exam

    【题目描述】
    你很快地完成了所有的题目,并且使准确率达到了p/q,于是开始无所事事. 老师
    看见了,对你说:“你今天做的题够多的了,别再做了. 我们接下来k 天每天都要模拟,这里有很多题,你去选一些题目编k 场模拟赛吧. ”老师将所有题目都编了序号,还给你了n 种出题方案(所有方案两两不同). 每种出题方案选择所有编号属于[l; r] 的题目,作为一天的试题. 现在,你需要选出k 种出题方案(一个方案只能选取一次),分别对应k 天的模拟赛. 老师非常强调复习的重要性,因此希望有一些题目每天都出现在模拟赛当中,你需要最大化每天都出现的题目的数量.
    【输入格式】
    从文件exam.in 中读入数据。
    输入第一行包含两个正整数n; k (1  <=k<=  n<=  3* 10^5),分别为出题方案数和模拟赛天数.接下来n 行,每行两个整数l; r (-10^9 <= l<=  r<=  109),表示一个出题方案(保证所有方案两两不同).
    【输出格式】
    输出到文件exam.out 中。
    输出一个非负整数,表示每天都出现的题目的数量的最大值.
    【样例1 输入】
    4 2
    1 100
    40 70
    120 130
    125 180
    【样例1 输出】
    31
    【样例1 解释】
    选择前两种方案,编号为[40; 70] 的题目在两种方案中均出现,共有31 道题.

    【样例2 输入】
    3 2
    1 12
    15 20
    25 30
    【样例2 输出】
    0
    【样例2 解释】
    所有给出的方案互不相交,所以答案为0.
    【样例3】
    见选手目录下的exam/exam3.in 与exam/exam3.ans。
    【子任务】
    对10% 的数据,k = n;
    对另20% 的数据,k = 2;
    对另20% 的数据,1 <= k <= n <= 20;
    其余5 组数据,n = 10^2; 10^3; 10^4; 10^5; 3 * 10^5.

    因为要从n种方案里选出k个,所以不妨把每个区间先按左端点排序,选出前k-1个,同时维护一个越小的整数优先级越高的单调队列,把它们的右端点存进去。然后看第k个区间,如果它的左端点小于前k-1个区间最小的右端点,它就是合法的。这时还需要将它的右端点和前k-1个区间最小的右端点(以下称为当前最小右端点)比较,如果它的右端点小于当前最小右端点,则它是被包含的,题目数量就是它自己的左右端点相减+1;否则,用当前最小右端点与它的左端点相减+1得到sum。然后将当前最小右端点出队,将现在第k个区间的右端点入队,以此类推。那么如果第k个区间的左端点大于当前最小右端点,则现在的状态无法满足某道题被选了k次,这时就要不断将队首元素出队,将第k个区间右端点入队,直到达到合法的状态。

    代码如下

     1 #include<cstdio>
     2 #include<algorithm> 
     3 #include<queue>
     4 using namespace std;
     5 #define ll long long int
     6 int k,n;
     7 ll sum,ans;
     8 struct node
     9 {
    10     ll l,r;
    11 }t[300005];
    12 ll cmp(node a,node b)
    13 {
    14     return a.l < b.l;//按左端点排序 
    15 }
    16 priority_queue<ll,vector<ll>,greater<ll> > pq;//越小的整数优先级越高 
    17 int main()
    18 {
    19     scanf("%d%d",&n,&k);
    20     for(int i = 1;i <= n;i++){
    21         scanf("%lld%lld",&t[i].l,&t[i].r);
    22     }
    23     sort(t+1,t+n+1,cmp);
    24     for(int i = 1;i < k;i++)
    25     {
    26         pq.push(t[i].r);//优先队列中存右端点 
    27     }
    28     for(int i = k;i <= n;i++)
    29     {
    30         if(t[i].l <= pq.top())
    31         {
    32             if(t[i].r > pq.top())
    33             {
    34                 sum = pq.top() - t[i].l + 1;
    35                 pq.pop();
    36                 pq.push(t[i].r);
    37             }
    38             else
    39             {
    40                 sum = t[i].r - t[i].l + 1;
    41             }
    42             ans = max(ans,sum);    
    43         }
    44         else
    45         {
    46             pq.pop();
    47             pq.push(t[i].r);
    48         }
    49     }
    50     printf("%lld",ans);
    51     return 0;
    52 }
  • 相关阅读:
    USACO 6.4 章节
    USACO 6.3 章节 你对搜索和剪枝一无所知QAQ
    USACO 6.1 章节
    USACO 5.5 章节
    USACO 5.4 章节
    USACO 5.3 章节
    99乘法表
    mini整数计算器
    python爬虫-爬取天气预报内容
    python实时监控服务器性能
  • 原文地址:https://www.cnblogs.com/peppa/p/9443481.html
Copyright © 2011-2022 走看看