377D Developing Game(线段树+扫描线)

 

D. Developing Game
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Pavel is going to make a game of his dream. However, he knows that he can't make it on his own so he founded a development company and hired n workers of staff. Now he wants to pick n workers from the staff who will be directly responsible for developing a game.

Each worker has a certain skill level vi. Besides, each worker doesn't want to work with the one whose skill is very different. In other words, the i-th worker won't work with those whose skill is less than li, and with those whose skill is more than ri.

Pavel understands that the game of his dream isn't too hard to develop, so the worker with any skill will be equally useful. That's why he wants to pick a team of the maximum possible size. Help him pick such team.

Input

The first line contains a single integer n (1 ≤ n ≤ 105) — the number of workers Pavel hired.

Each of the following n lines contains three space-separated integers li, vi, ri (1 ≤ li ≤ vi ≤ ri ≤ 3·105) — the minimum skill value of the workers that the i-th worker can work with, the i-th worker's skill and the maximum skill value of the workers that the i-th worker can work with.

Output

In the first line print a single integer m — the number of workers Pavel must pick for developing the game.

In the next line print m space-separated integers — the numbers of the workers in any order.

If there are multiple optimal solutions, print any of them.

Sample test(s)
input
4
2 8 9
1 4 7
3 6 8
5 8 10
output
3
1 3 4
input
6
3 5 16
1 6 11
4 8 12
7 9 16
2 10 14
8 13 15
output
4
1 2 3 5


题意:有n个开发人员,每个人有个技能值vi,每个人不想和技能值不在区间[li,ri]的人合作,现在要选尽可能多的人,使得满足所有选中的人的要求。

 

思路:首先,如果我们能求出一组L,R,使得每个选中的人i都满足li<=L<=R<=ri并且L<=vi<=R,那么我们就能找到应该选出的人。那么如何求这个L和R呢,把L,R想象成坐标系中的一个点,那么对于每一个人,需要满足li<=L<=vi并且vi<=R<=ri,这样,每个人可以看成一个矩形,问题就变成了寻找一个点使得有最多的矩形覆盖,这个问题可以用线段树+扫描线处理。

 

代码:

 

#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define ls ( o << 1 )
#define rs ( o << 1 | 1 )
#define lson ls , l , mid
#define rson rs , mid + 1 , r
#define root 1 , 1 , n
#define rt o , l , r

vector <int> v1[300005],v2[300005];
int L[100005],V[100005],R[100005];
int N,ans;
int a,b;

struct node
{
    int x,w,c;//c表示子节点是否需要更新,0表示不用,
    
//w存的是当前节点的最左端,x表示最大的覆盖数
}s[1<<20];

void build (int o , int l , int r)
{
    s[o].c = s[o].x = 0;
    if (l == r)
    {
        s[o].w = l;
        return;
    }
    int mid = ( l + r ) >> 1;
    build(lson);
    build(rson);
    s[o].w = s[ls].w;
}
void pushdown(int o)
{
    s[ls].x += s[o].c;
    s[rs].x += s[o].c;
    s[ls].c += s[o].c;
    s[rs].c += s[o].c;
    s[o].c = 0;
}
void update(int o , int l , int r , int le , int re , int v)
{
    if(l <= le && re <= r)
    {
        s[o].x += v;
        s[o].c += v;
        return ;
    }
    if(s[o].c != 0) pushdown(o);
    int mid = ( le + re ) >> 1;
    if(r > mid)
        update(rs, l, r , mid+1 , re , v);
    if(l <= mid)
        update(ls, l, r , le , mid , v);

    if(s[ls].x < s[rs].x)
    {
        s[o].x = s[rs].x;
        s[o].w = s[rs].w;
    }
    else
    {
        s[o].x = s[ls].x;
        s[o].w = s[ls].w;
    }
}
int main()
{
    scanf("%d",&N);
    for(int i=0; i<N; i++)
    {
        scanf("%d%d%d",L+i,V+i,R+i);
        v1[L[i]].push_back(i);
        v2[V[i]].push_back(i);
    }
    build(1,1,3e5);
    for(int i=1; i<=3e5; i++)
    {
        for(int j=0; j<v1[i].size(); j++)
        {
            update(1,V[v1[i][j]],R[v1[i][j]],1,3e5,1);
            //printf("i=%d , v1=%d , V=%d , R=%d\n",i,v1[i][j],V[v1[i][j]],R[v1[i][j]]);
        }
        if(ans<s[1].x)
        {
            ans=s[1].x, a=i, b=s[1].w;
            //printf("ans=%d , a=%d , b=%d\n",ans,a,b);
        }
        for(int j=0; j<v2[i].size(); j++)
        {
            update(1,i,R[v2[i][j]],1,3e5,-1);
            //printf("i=%d , v2=%d , i=%d , R=%d\n",i,v2[i][j],V[v2[i][j]],R[v2[i][j]]);
        }
    }
    printf("%d\n",ans);
    for(int i=0; i<N; i++)
    {
        if(L[i]<=a&&a<=V[i]&&V[i]<=b&&b<=R[i])
            printf("%d ",i+1);
    }
    return 0;
}
View Code

 

posted @ 2015-06-05 11:50  Doli  阅读(262)  评论(0)    收藏  举报