http://codeforces.com/problemset/problem/754/D
All our characters have hobbies. The same is true for Fedor. He enjoys shopping in the neighboring supermarket.
The goods in the supermarket have unique integer ids. Also, for every integer there is a product with id equal to this integer. Fedor has n discount coupons, the i-th of them can be used with products with ids ranging from li to ri, inclusive. Today Fedor wants to take exactly k coupons with him.
Fedor wants to choose the k coupons in such a way that the number of such products x that all coupons can be used with this product x is as large as possible (for better understanding, see examples). Fedor wants to save his time as well, so he asks you to choose coupons for him. Help Fedor!
InputThe first line contains two integers n and k (1 ≤ k ≤ n ≤ 3·105) — the number of coupons Fedor has, and the number of coupons he wants to choose.
Each of the next n lines contains two integers li and ri ( - 109 ≤ li ≤ ri ≤ 109) — the description of the i-th coupon. The coupons can be equal.
In the first line print single integer — the maximum number of products with which all the chosen coupons can be used. The products with which at least one coupon cannot be used shouldn't be counted.
In the second line print k distinct integers p1, p2, ..., pk (1 ≤ pi ≤ n) — the ids of the coupons which Fedor should choose.
If there are multiple answers, print any of them.
4 2 1 100 40 70 120 130 125 180
31 1 2
3 2 1 12 15 20 25 30
0 1 2
5 2 1 10 5 15 14 50 30 70 99 100
21 3 4
In the first example if we take the first two coupons then all the products with ids in range [40, 70] can be bought with both coupons. There are 31 products in total.
In the second example, no product can be bought with two coupons, that is why the answer is 0. Fedor can choose any two coupons in this example.
The meaning of the question: Each product corresponds to a number, there are n coupons, and each coupon can discount the products in the range from left to right. Now select k coupons, and ask how many products can be discounted k times at most. How to choose coupons?
Idea: The interval is sorted first. In this question, the interval should be sorted by the size of L. The smallest L is in the front, and the row of R will not be affected.
After sorting, the overlapping part of the k intervals you selected is determined by the smallest R and the largest L among them . L is already sorted, and all Ls are greater than or equal to the previous L, so L need not be used any more. Consider that the current L is the largest . The smallest R is maintained by a priority queue. In the k intervals you choose, take out the smallest R and compare whether it is better than the original solution (R-L+1), and if it is better, follow the new one. Delete the smallest R of the k intervals each time (removing the smallest R is optimal, and the larger the remaining R, the better), the selected overlapping interval can be determined by two elements (interval length and L), so each Update the answer every time, and save the optimal L value.
Code:
#include <iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<queue> #include<algorithm> #define N 300500 #define mem(a,b) memset(a,b,sizeof(a)); using namespace std; struct node { int l,r,id; } a[N]; bool cmp(node b,node c) { if(b.l==c.l) return b.r<c.r; return b.l<c.l; } priority_queue<int, vector<int>, greater<int> > q;//Priority queue, small priority, if you don't have a priority queue, you can Baidu it yourself intmain() { int n,k; scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) { scanf("%d%d",&a[i].l,&a[i].r); a[i].id=i;//Save the number of the interval, because it will be sorted in a while. } sort(a+1,a+1+n,cmp); int ans=0,t=0;//ans represents the maximum interval length, t represents the left endpoint of the interval of the optimal solution for(int i=1; i<=k-1; i++) q.push(a[i].r);//First select k-1 intervals and put R into the queue for(int i=k; i<=n; i++)//Select the i-th one each time, delete the one with the smallest R, there are k-1 intervals in the maintenance queue { q.push(a[i].r); int w=q.top();//q.top() is the minimum value of r in the returned queue, if(ans<w-a[i].l+1) { ans=wa[i].l+1;//Update answer t=a[i].l;//Update the left endpoint of the answer } q.pop();//Delete the smallest r } if(ans==0)//The answer is zero, so output { printf("0\n"); for(int i=0; i<k; i++) { if(i) printf(" "); printf("%d",i+1); } printf("\n"); return 0; } printf("%d\n",ans); int flag=0; for(int i=1; i<=n; i++) { if(k&&a[i].l<=t&&a[i].r>=ans+t-1)//All intervals including the interval [t,t+ans-1] can be selected. { k--;//A total of k outputs if(flag) printf(" "); printf("%d",a[i].id); flag=1; } } printf("\n"); }