分析:
最长不降子序列,n很大o(n^2)肯定超,想到了小明序列那个题用线段树维护前面的最大值即可
该题也可用二分搜索来做。
注意问题输出时的坑,路复数后加s
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<1|1 #define All 1,N,1 #define N 500010 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; struct city{ int p,r; }t[N]; bool cmp(city x,city y){ return x.p<y.p; } int maxv[N*4],n,dp[N]; void pushup(int rt){ maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]); } void build(int l,int r,int rt){ maxv[rt]=0; if(l==r){ return; } int m=(l+r)>>1; build(lson); build(rson); } void update(int p,int v,int l,int r,int rt){ if(l==r){ maxv[rt]=max(maxv[rt],v); return; } int m=(l+r)>>1; if(p<=m)update(p,v,lson); else update(p,v,rson); pushup(rt); } int query(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r) return maxv[rt]; int m=(l+r)>>1; int ans=0; if(L<=m)ans=max(ans,query(L,R,lson)); if(R>m)ans=max(ans,query(L,R,rson)); return ans; } int main() { int ca=0; while(~scanf("%d",&n)){ memset(dp,0,sizeof(dp)); for(int i=0;i<n;++i) scanf("%d%d",&t[i].p,&t[i].r); sort(t,t+n,cmp); build(1,n,1); int maxn=0; for(int i=0;i<n;++i){ dp[i]=query(1,t[i].r,1,n,1)+1; maxn=max(maxn,dp[i]); update(t[i].r,dp[i],1,n,1); } printf("Case %d:\n",++ca); if(maxn>1) printf("My king, at most %d roads can be built.\n",maxn); else printf("My king, at most %d road can be built.\n",maxn); printf("\n"); } return 0; }
HDU 1025-Constructing Roads In JGShining's Kingdom(最长不降子序列,线段树优化)
时间: 2024-10-19 16:33:01