codeforces527D

时间:2019-04-19
本文章向大家介绍codeforces527D,主要包括codeforces527D使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Clique Problem

 CodeForces - 527D 

所谓图的极大团是指在一个无向图中找到最多的点,使得这些点构成的图(即导出子图)是一个完全图,然而这个问题至今没有有效的多项式解法,当然在某些特殊条件下,这个问题具备多项式解法。

我们给出数轴上n个互不相同的点,对于每个点i(1<=i<=n),都有两个属性:坐标xi和重量wi。对于任意的两个点,当它们的距离大于等于它们的重量之和时,它们之间就连有一条边。
 
现在要求你针对这个特殊的图求出它的极大团中有几个点。

Input

输入的第一行是一个正整数n,表示有几个互不相同的点。
接下来n行,每行两个整数x, w,表示第i个点的坐标和重量。
 
n<=200000
其中 0<=xi<=10^9 1<=wi<=10^9
保证点的坐标互不相同

Output

输出一个整数,为极大团的点数。

Sample Input

 
4
2 3
3 1
6 1
0 2
 

Sample Output

3

Hint

样例如图:

sol:这题咋一看似乎Div2的D,其实也就Div2的A题的难度

令Xi>Xj,则当Xi-Xj >= Wi+Wj时有连边,移项以后就是 Xi-Wi >= Xj+Wj

然后就得到一个序列,每个元素有两个变量F1,F2,答案就是让你求一个最长不下降子序列满足每一项的F1>前一项的F2,因为是1e9,所以离散以下,套上树状数组模板即可

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0');    return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=200005;
int n,dp[N];
int Hash[N<<1];
struct Point
{
    int X,W,F1,F2;
}P[N];
inline bool cmp_X(Point p,Point q)
{
    return p.X<q.X;
}
struct BIT
{
    int Max[N<<1];
    #define lowbit(x) ((x)&(-x))
    inline void Ins(int x,int Val)
    {
        while(x<=*Hash)
        {
            Max[x]=max(Max[x],Val);
            x+=lowbit(x);
        }
    }
    inline int Que(int x)
    {
        int ans=0;
        while(x)
        {
            ans=max(ans,Max[x]);
            x-=lowbit(x);
        }
        return ans;
    }
}T;
int main()
{
    int i,ans=0;
    R(n);
    for(i=1;i<=n;i++)
    {
        R(P[i].X); R(P[i].W);
        P[i].F1=P[i].X-P[i].W; 
        P[i].F2=P[i].X+P[i].W;
        Hash[++*Hash]=P[i].F1;
        Hash[++*Hash]=P[i].F2;
    }
    sort(P+1,P+n+1,cmp_X);
    sort(Hash+1,Hash+*Hash+1);
    *Hash=unique(Hash+1,Hash+*Hash+1)-Hash-1;
    for(i=1;i<=n;i++)
    {
        P[i].F1=lower_bound(Hash+1,Hash+*Hash+1,P[i].F1)-Hash;
        P[i].F2=lower_bound(Hash+1,Hash+*Hash+1,P[i].F2)-Hash;
    }
    for(i=1;i<=n;i++)
    {
        dp[i]=T.Que(P[i].F1)+1;
        T.Ins(P[i].F2,dp[i]);
        ans=max(ans,dp[i]);
    }
    Wl(ans);
    return 0;
}
/*
Input
4
2 3
3 1
6 1
0 2
Output
3
*/
View Code