clique

【题目描述】
数轴上有 n 个点,第 i 个点的坐标为 xi,权值为 wi。两个点 i,j 之
间存在一条边当且仅当 abs(xi-xj)>=wi+wj。
你需要求出这张图的最大团的点数。
(团就是两两之间有边的顶点
集合)
【输入数据】
第一行一个整数 n,接下来 n 行每行两个整数 xi,wi。
【输出数据】
一行一个整数表示答案。
【样例输入】
4
2 3
3 1
6 1
0 2
【样例输出】
3
【数据范围】
对于 20%的数据,n<=10。
对于 60%的数据,n<=1000。
对于 100%的数据,n<=200000,0<=|xi|,wi<=10^9。

先按x排序,则连边条件变为:

xi-xj>=wi+wj

xi-wi>=xj+wj

于是建边的条件可以理解为:有两个区间[xi-wi,xi+wi],[xj-wj,xj+wj],如果区间不相交那么连边

于是完全图就相当于求最长的不相交区间集

这里用的是dp+线段树+离散

把每一个xi+wi,xi-wi离散

然后每一次查询线段树上位于区间左边的最大f值

然后在线段树上更新当前右端点为当前f

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long lol;
 7 struct Node
 8 {
 9   lol l,r;
10 }a[200001];
11 lol c[1600001],n,m,s[400001],num,sz,f[200001],ans;
12 bool cmp(Node a,Node b)
13 {
14   return a.r<b.r;
15 }
16 lol query(int rt,int l,int r,int L,int R)
17 {
18   if (l>=L&&r<=R)
19     {
20       return c[rt];
21     }
22   int mid=(l+r)/2;
23   lol s=0;
24   if (L<=mid) s=max(s,query(rt*2,l,mid,L,R));
25   if (R>mid) s=max(s,query(rt*2+1,mid+1,r,L,R)); 
26   c[rt]=max(c[rt*2],c[rt*2+1]);
27  return s;
28 }
29 void update(int rt,int l,int r,int x,lol d)
30 {
31   if (l==r)
32     {
33       c[rt]=max(c[rt],d);
34       return;
35     }
36   int mid=(l+r)/2;
37   if (x<=mid) update(rt*2,l,mid,x,d);
38   else update(rt*2+1,mid+1,r,x,d);
39   c[rt]=max(c[rt*2],c[rt*2+1]); 
40 }
41 int main()
42 {int i;
43   lol w,x;
44   cin>>n;
45   for (i=1;i<=n;i++)
46     {
47       scanf("%lld%lld",&x,&w);
48       a[i].l=x-w;a[i].r=x+w;
49       s[++num]=x-w;s[++num]=x+w;
50     }
51   sort(a+1,a+n+1,cmp);
52   sort(s+1,s+num+1);
53   sz=unique(s+1,s+num+1)-(s+1);
54   //cout<<sz<<endl;
55   for (i=1;i<=n;i++)
56     {
57       a[i].l=lower_bound(s+1,s+sz+1,a[i].l)-s;
58       a[i].r=lower_bound(s+1,s+sz+1,a[i].r)-s;
59     }
60   for (i=1;i<=n;i++)
61     {
62       f[i]=query(1,1,sz,1,a[i].l)+1;
63       ans=max(ans,f[i]);
64       update(1,1,sz,a[i].r,f[i]);
65     }
66   cout<<ans;
67 }

 

posted @ 2017-11-06 14:45  Z-Y-Y-S  阅读(313)  评论(0编辑  收藏  举报