题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5324
题意:给你一个二维的序列,让你找出最长的第一维升第二维降的子序列(如果多个答案,输出字典序最小)
解:考虑从后往前dp,在u点你需要知道u点之后的比u的第一维大,第二维小的dp最大值
可以用分治枚举u点之后比u的第一维大的点,然后用树状数组查询比u的第二维小的点中dp最大的
1 /* 2 * Problem: 3 * Author: SHJWUDP 4 * Created Time: 2015/8/3 星期一 21:14:55 5 * File Name: 233.cpp 6 * State: 7 * Memo: 8 */ 9 #include <iostream> 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 14 using namespace std; 15 16 const int INF=0x7f7f7f7f; 17 18 const int MaxA=5e4+7; 19 20 struct Node { 21 int l, r, id; 22 bool operator<(const Node & rhs) const { 23 return r<rhs.r; 24 } 25 }; 26 struct Hash : vector<int> { 27 void prepare() { 28 sort(begin(), end()); 29 erase(unique(begin(), end()), end()); 30 } 31 int get(int x) { 32 return lower_bound(begin(), end(), x)-begin()+1; 33 } 34 }; 35 struct Fenwick { 36 int n; 37 vector<pair<int, int> > c; 38 void init(int n) { 39 this->n=n; 40 c.assign(n+1, make_pair(0, -INF)); 41 } 42 int lowbit(int x) { 43 return x & -x; 44 } 45 void modify(int x, pair<int, int> v) { 46 while(x<=n) { 47 c[x]=v; x+=lowbit(x); 48 } 49 } 50 void update(int x, pair<int, int> v) { 51 while(x<=n) { 52 c[x]=max(c[x], v); x+=lowbit(x); 53 } 54 } 55 pair<int, int> query(int x) { 56 pair<int, int> res(0, -INF); 57 while(x>0) { 58 res=max(res, c[x]); x-=lowbit(x); 59 } 60 return res; 61 } 62 } fw; 63 64 int n; 65 vector<Node> arr, tmp; 66 vector<pair<int, int> > dp; 67 void dc(int l, int r) { 68 if(l==r) return; 69 int m=(l+r)>>1; 70 dc(m+1, r); 71 for(int i=l; i<=r; i++) tmp[i]=arr[i]; 72 sort(tmp.begin()+l, tmp.begin()+m+1); 73 sort(tmp.begin()+m+1, tmp.begin()+r+1); 74 int pr=r; 75 for(int i=m; i>=l; i--) { 76 int cid=tmp[i].id; 77 while(pr>m && tmp[pr].r>=tmp[i].r) { 78 fw.update(tmp[pr].l, make_pair(dp[tmp[pr].id].first+1, -tmp[pr].id)); 79 pr--; 80 } 81 dp[cid]=max(dp[cid], fw.query(tmp[i].l)); 82 } 83 for(int i=m+1; i<=r; i++) fw.modify(tmp[i].l, make_pair(0, -INF)); 84 dc(l, m); 85 } 86 int main() { 87 #ifndef ONLINE_JUDGE 88 freopen("in", "r", stdin); 89 //freopen("out", "w", stdout); 90 #endif 91 while(~scanf("%d", &n)) { 92 arr.resize(n+1); tmp.resize(n+1); 93 Hash hash; 94 for(int i=1; i<=n; i++) { 95 scanf("%d", &arr[i].l); 96 arr[i].id=i; 97 hash.push_back(arr[i].l); 98 } 99 hash.prepare(); 100 for(int i=1; i<=n; i++) arr[i].l=hash.get(arr[i].l); 101 hash.clear(); 102 for(int i=1; i<=n; i++) { 103 scanf("%d", &arr[i].r); 104 hash.push_back(arr[i].r); 105 } 106 hash.prepare(); 107 for(int i=1; i<=n; i++) arr[i].r=hash.get(arr[i].r); 108 fw.init(n+1); 109 dp.assign(n+1, make_pair(1, -INF)); 110 dc(1, n); 111 pair<int, int> ans(0, -INF); 112 int stPos; 113 for(int i=1; i<=n; i++) { 114 if(dp[i]>ans) { 115 ans=dp[i]; stPos=i; 116 } 117 } 118 printf("%d\n", ans.first); 119 printf("%d", stPos); 120 for(int i=-ans.second; i!=INF; i=-dp[i].second) printf(" %d", i); 121 printf("\n"); 122 } 123 return 0; 124 }
hdu5324
时间: 2024-10-08 10:29:28