[HAOI2011]Problem A

Description:

一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低。”问最少有几个人没有说真话(可能有相同的分数)

Hint:

\(n \le 10^5\)

Solution:

题目给的信息相当与\([a+1,n-b]\)的分数相等
于是问题转化为从一些带权区间中选出一些没有交集的区间的权值和最大

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1 
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=1e5+5;
int n,m,cnt,hd[mxn];

inline int read() {
    char c=getchar(); int x=0,f=1;
    while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
    return x*f;
}
inline void chkmax(int &x,int y) {if(x<y) x=y;}
inline void chkmin(int &x,int y) {if(x>y) x=y;}

struct ed {
    int to,nxt;
}t[mxn<<1];

inline void add(int u,int v) {
    t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
}

int tot,f[mxn];

struct T {
    int l,r,val;
}a[mxn],b[mxn];

int cmp(T x,T y) {
    return x.l==y.l?x.r<y.r:x.l<y.l;
}

int cmp1(T x,T y) {
    return x.r==y.r?x.l<y.l:x.r<y.r;
}

int find(int l,int r,int x) {
    while(l<r) {
        int mid=(l+r+1)>>1;
        if(a[mid].r<x) l=mid; //利用答案的单调性进行二分查找优化
        else r=mid-1;
    }
    return l;
}

int main()
{
    n=read(); int sum=n;
    for(int i=1;i<=n;++i) a[i].l=read()+1,a[i].r=n-read();
    sort(a+1,a+n+1,cmp); 
    for(int i=1;i<=n;++i) 
        if(a[i].l<=a[i].r) b[++tot]=a[i];/*去除一定说谎的*/ n=0;
    for(int i=1;i<=tot;++i) 
        if(i==1||b[i].l!=b[i-1].l||b[i].r!=b[i-1].r)
            a[++n]=b[i],a[n].val=1;
        else if(a[n].val<a[n].r-a[n].l+1) ++a[n].val; //去除一定说谎的
    sort(a+1,a+n+1,cmp1); f[1]=a[1].val;
    for(int i=2;i<=n;++i) {
        int pos=find(1,i-1,a[i].l);
        f[i]=max(f[i-1],f[pos]+a[i].val); //dp
    }
    printf("%d",sum-f[n]);
    return 0;
}

转载于:https://www.cnblogs.com/list1/p/10614802.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值