Clique Problem
所谓图的极大团是指在一个无向图中找到最多的点,使得这些点构成的图(即导出子图)是一个完全图,然而这个问题至今没有有效的多项式解法,当然在某些特殊条件下,这个问题具备多项式解法。
我们给出数轴上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(' ') 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 */