cdq分治

  1 /*
  2   题意:
  3   题解:cdq分治
  4   时间:
  5 */
  6 
  7 #include <bits/stdc++.h>
  8 using namespace std;
  9 
 10 typedef long long LL;
 11 const int MAXN = 100005;
 12 const LL MOD7 = 1e9+7;
 13 
 14 inline int read()
 15 {
 16     int x=0,f=1;char c=getchar();
 17     while (c<'0' || c>'9') { c=='-'&&(f=-1); c=getchar();}
 18     while (c>='0' && c<='9') {x=x*10+c-'0';c=getchar();}
 19     return x*f;
 20 }
 21 
 22 inline int lowbit(int x) {return x&(-x);}
 23 
 24 
 25 struct Node
 26 {
 27     int x,y;
 28     int idx;
 29 }node[MAXN];
 30 
 31 int cmp(Node na, Node nb)
 32 {
 33     return na.x<nb.x;
 34 }
 35 
 36 int cmp2(Node na, Node nb)
 37 {
 38     return na.idx<nb.idx;
 39 }
 40 
 41 int n;
 42 
 43 int a[MAXN];
 44 int cnt;
 45 map<int, int> mp;
 46 
 47 struct BitArray
 48 {
 49     int c[MAXN];
 50     int n;
 51     void init(int n)
 52     {
 53         this->n=n+5;
 54     }
 55     void add(int x,int v)
 56     {
 57         // printf("%d\n",n);
 58         while (x<n)
 59         {
 60             c[x]=max(c[x],v);
 61             x+=lowbit(x);
 62         }
 63     }
 64 
 65     int query(int x)
 66     {
 67         int ans=0;
 68         while (x>0)
 69         {
 70             ans=max(ans, c[x]);
 71             x-=lowbit(x);
 72         }
 73         return ans;
 74     }
 75 
 76     void reset(int x)
 77     {
 78         while (x<n)
 79         {
 80             c[x]=0;
 81             x+=lowbit(x);
 82         }
 83     }
 84 }bt;
 85 
 86 int dp[MAXN];
 87 
 88 void cdq(int l,int r)
 89 {
 90     if (l==r) return;
 91     int mid=(l+r)/2;
 92     cdq(l,mid);
 93 
 94     sort(node+l,node+mid+1,cmp);
 95     sort(node+mid+1,node+r+1,cmp);
 96     int j=l;
 97     for (int i=mid+1;i<=r;++i)
 98     {
 99         for (;j<=mid&&node[j].x<node[i].x;++j) bt.add(node[j].y,dp[node[j].idx]);
100         dp[node[i].idx]=max(dp[node[i].idx],bt.query(node[i].y-1)+1);
101     }
102     for (int i=l;i<=mid;++i) bt.reset(node[i].y);
103     sort(node+mid+1,node+r+1,cmp2);
104 
105     cdq(mid+1,r);
106 }
107 
108 int main()
109 {
110 #ifndef ONLINE_JUDGE
111     freopen("test.txt","r",stdin);
112 #endif // ONLINE_JUDGE
113     n=read();
114     for (int i=1;i<=n;++i)
115     {
116         node[i].x=read();
117         node[i].y=read();
118         a[cnt++]=node[i].y;
119         node[i].idx=i;
120         dp[i]=1;
121     }
122     sort(a,a+cnt);
123     cnt = unique(a,a+cnt) - a;
124     // for (int i=0;i<cnt;++i) printf("%d ",a[i]);printf("\n");
125     mp.clear();
126     for (int i=0;i<cnt;++i) mp[a[i]]=i+2;
127     for (int i=1;i<=n;++i) node[i].y=mp[node[i].y];
128     bt.init(cnt);
129     cdq(1,n);
130     int ans=0;
131     for (int i=1;i<=n;++i) ans = max(ans, dp[i]);
132     printf("%d\n",ans);
133     return 0;
134 }

 

转载于:https://www.cnblogs.com/LeeSongt/p/9341862.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值