zoukankan      html  css  js  c++  java
  • bzoj 2298 problem a

    Written with StackEdit.

    Description

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

    Input

    第一行一个整数(n),接下来(n)行每行两个整数,第(i+1)行的两个整数分别代表(a_i,b_i.)

    Output

    一个整数,表示最少有几个人说谎.

    Sample Input

    3

    2 0

    0 2

    2 2

    Sample Output

    1

    HINT

    (100\%)的数据满足: (1≤n≤100000 0≤a_i,b_i≤n.)

    Solution

    • 一句话题面系列...
    • 关键在于条件的转化.有(a)个人严格比他大,(b)个人严格比他小,
    • 若将分数从大到小排序,如果这句话为真,那么易知:
    • 性质1这个人的分数一定属于([a+1,n-b]),且这个区间内所有人的分数都相同.
    • 性质2这个区间外的分数都与区间内的分数不同.
    • 首先可以排除掉区间左端点大于右端点的人,这些话一定为假.
    • 对于剩下的人,我们假设这些话都为真,可以得到若干个区间.
    • 如果两个区间相交,而又不完全重合,将这两个区间并起来显然可以得到更大的分数相同区间,不符合性质2.而对于完全相同的两个区间,而根据性质1,针对这个区间的话,最多可以有(r-l+1)(区间长度)句话为真.
    • 那么可以给每个区间赋一个权值,为这个区间的重复次数与区间长度的最小值.我们现在选出若干个不相交的区间,这些区间的最大权值和即为最多说真话的人数.
    • 这里就是一个(dp)了.优化方法多样,我选择无需思考的树状数组.
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LoveLive;
    inline int read()
    {
    	int out=0,fh=1;
    	char jp=getchar();
    	while ((jp>'9'||jp<'0')&&jp!='-')
    		jp=getchar();
    	if (jp=='-')
    		{
    			fh=-1;
    			jp=getchar();
    		}
    	while (jp>='0'&&jp<='9')
    		{
    			out=out*10+jp-'0';
    			jp=getchar();
    		}
    	return out*fh;
    }
    const int MAXN=1e5+10;
    int n,tot,unitot;
    struct sec{
    	int l,r;
    	int w;
    	bool operator < (const sec& rhs) const
    		{
    			return r==rhs.r?l<rhs.l:r<rhs.r;
    		}
    }s[MAXN],p[MAXN];
    #define lowbit(x) x&(-x)
    int bit[MAXN];
    inline void upd(int x,int c)
    {
    	for(;x<=n;x+=lowbit(x))
    		bit[x]=max(bit[x],c);	
    }
    inline int query(int x)
    {
    	if(x<=0)
    		return 0;
    	int res=0;
    	for(;x;x-=lowbit(x))
    		res=max(res,bit[x]);
    	return res;
    }
    void UniqueSec()
    {
    	for(int i=1;i<=tot;++i)
    		{
    			if(i==1 || s[i].l!=s[i-1].l || s[i].r!=s[i-1].r)
    				++unitot;
    			p[unitot].w=min(p[unitot].w+1,p[unitot].r-p[unitot].l+1);
    			p[unitot].l=s[i].l;
    			p[unitot].r=s[i].r;
    		}
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)
    		{
    			int a=read(),b=read();
    			int l=a+1;
    			int r=n-b;
    			if(l<=r)
    				{
    					s[++tot].l=l;
    					s[tot].r=r;
    				}
    		}
    	sort(s+1,s+1+tot);
    	UniqueSec();
    	for(int i=1;i<=unitot;++i)
    		{
    			int l=p[i].l,r=p[i].r;
    			int val=query(l-1)+p[i].w;
    			upd(r,val);
    		}
    	int ans=n-query(n);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    为https请求配置ssl(不用keystore,直接用证书,rsa私钥,java代码)
    http请求对于List类型参数的处理
    java中string转ByteBuffer
    lua for循环如何从第0位开始
    lua中的cjson简单使用
    mongodb返回方便读的数据
    markdown简单插入图片
    #问题#java报Annotation processing is not supported for module cycles
    #问题#java报can't create non-static inner class instance
    git commit+push的完整步骤
  • 原文地址:https://www.cnblogs.com/jklover/p/10108787.html
Copyright © 2011-2022 走看看