[2015hdu多校联赛补题]hdu5324 Boring Class

题目链接: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

[2015hdu多校联赛补题]hdu5324 Boring Class的相关文章

[2015hdu多校联赛补题]hdu5371 Hotaru&#39;s problem

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5371 题意:把一个数字串A翻过来(abc翻过来为cba)的操作为-A,我们称A-AA这样的串为N-sequence,现在给你一个数字串,问你这个串中最长的N-sequence子串长度 解:可以想到A-A是一个回文串,-AA也是一个回文串,那么首先Manacher跑一遍求出所有回文子串 可以想到任意两个互相覆盖的回文子串都可以表示成N-sequence 然后有三种搞法: 1.时间复杂度O(N*logN

[2015hdu多校联赛补题]hdu5348 MZL&#39;s endless loop

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5348 题意:给你一个无向图,要你将无向图的边变成有向边,使得得到的图,出度和入度差的绝对值小于等于1,如果无解输出-1 解:考虑奇数度的点一定会成对出现(因为所有度数和肯定是偶数个->因为一条边产生两度~),那么我们可以将奇数度的点两两一连消除掉(两奇数度点的出度入读差的绝对值都为1, 路径上的点的差绝对值为0) 然后偶数度的点可以成环,那么可以搜出所有的环 1 /* 2 * Problem: 3

[2015hdu多校联赛补题]hdu5302 Connect the Graph

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5302 题意:给你一个无向图,它的边要么是黑色要么是白色,且图上的每个点最多与两个黑边两个白边相连.现在,Demon将图分成两部分,一部分包含所有的黑边,另一部分包括所有的白边,给你白边图中度为0的点的数量w0,度为1的点数w1,度为2的点数w2,与黑边图中度为0的点数b1,度为1的点数b1,度为2的点数b2,要你输出任意一个符合条件的原图,如果不能,输出-1 (注1:无论是黑边图,还是白边图,给出的

[2015hdu多校联赛补题]hdu5384 Danganronpa

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384 题意:函数f(A, B)定义:A.B为字符串,f(A, B)为A中有多少个不同的B(ex:f("ababa", "aba")==2   f("ababa", "bab")==1),现在给你一组A串,一组B串,问你对每个A串的是多少 解:ac自动机模板题,可以把A串用'z'+1,连成一个串处理起来比较方便 1 /* 2 * P

[2015hdu多校联赛补题]hdu5378 Leader in Tree Land

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5378 题意:给你一棵n个结点的有根树.因为是有根树,那么每个结点可以指定以它为根的子树(后面讨论的子树都是这个).现在我们把标号从1到n的n个minister派驻到这些结点上面(每个结点派驻一人),并规定任一子树中编号最大的minister 为该子树的领导,问你存在多少个不同的领导 解: 引用官方题解: 可以用求概率的思想来解决这个问题.令以i号节点为根的子树为第i棵子树,设这颗子树恰好有sz[i]

[2015hdu多校联赛补题]hdu5372 Segment Game

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5372 题意:进行n次操作,操作分两种,0和1,每一个0操作按出现顺序有一个编号(从1开始 0操作 0 x:询问[x, x+i](i为该操作的编号)区间内有多少个完整的线段,并加入线段[x, x+i](线段直接重叠不影响) 1操作 1 x:删除0操作中插入的编号为x的线段,(不影响其他线段,不会重复删除同一线段,删除的线段一定是已经插入的) 解:题目有一个重要的条件:后面插入的线段一定比前面的长.那么

[2015hdu多校联赛补题]hdu5301 Buildings

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5301 题目大意:给你一块由1x1方格组成的矩形区域,其中有且仅有一个坏块,现在你要在上面建矩形的房子, 要求: 1.除坏块以外任何一个1x1方格上都要有房子覆盖 2.任何一座房子都必须有一部分作为矩形区域的边界 3.要使所建房子中面积最大的面积尽量小 要你输出这个所建房子中面积最大的那个房子的面积 解: 大概想一下,面积最大的房子肯定是1*x的长条,因为对任何y来说1*x的长条都可以拼成y*x的长条

[2015hdu多校联赛补题]hdu 5297 Y sequence

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5297 题意:给你一个所有正整数的序列,然后去掉满足x^(2~r)的所有数(x为所有正整数,r>=2题目给出),问你现在这个序列的第n个数是什么 解:首先想到写一个函数func(y),它可以计算出给定数字y是序列中第几个数,这样我们大概可以二分答案~(事实上会TLE,得用迭代法,当然迭代的话也是用这个函数) 那么如何实现func: 首先想去掉满足x^2的所有数,我们可以用pow(y, 1/2)计算出y

[2015hdu多校联赛补题]hdu5293 Tree chain problem

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意:给你一棵n个点的树,和一些该树上的树链,每个树链有一定的权值,要求选出一些不相交的树链,使他们的权值和尽量大 解: 树形dp,dp[x]表示以x为根节点的子树的解,那么就可以基于在当前结点对树链的选和不选进行dp 现在有两个问题: 1.在树链上的哪个点进行选择? 2.选和不选分别如何操作? 对于第一个问题,粗略想一下(在解决问题二的时候会发现),树链上最浅的一个点(也就是树链两端的lca