zoukankan      html  css  js  c++  java
  • 【HEOI2016】序列

    题面

    题解

    很像最长不下降子序列对吧(废话)

    设$up[i]$和$down[i]$分别表示$i$最大最小能取多少

    注意到:

    $$ f[i] = max_jleft{f[j] ight} + 1 \ a[j] leq down[i],; up[j] leq a[i],; j leq i $$

    三位偏序!!!

    $CDQ$分治走起

    代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #define RG register
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while(ch != '-' && (!isdigit(ch))) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    using std::max;
    const int maxn(100010);
    int n, m, a[maxn], up[maxn], down[maxn], c[maxn], f[maxn], Max;
    inline bool cmp_1(int x, int y) { return a[x] < a[y]; }
    inline bool cmp_2(int x, int y) { return down[x] < down[y]; }
    void clean(int x) { while(x <= Max) c[x] = 0, x += x & -x; }
    void add(int x, int v) { while(x <= Max) c[x] = max(c[x], v), x += x & -x; }
    int query(int x)
    {
    	int ans = 0;
    	while(x) ans = max(ans, c[x]), x -= x & -x;
    	return ans;
    }
    
    void Div(int l, int r)
    {
    	static int id[maxn];
    	if(l == r) return (void)(f[l] = max(f[l], 1));
    	int mid = (l + r) >> 1; Div(l, mid);
    	for(RG int i = l; i <= r; i++) id[i] = i;
    	std::sort(id + l, id + mid + 1, cmp_1);
    	std::sort(id + mid + 1, id + r + 1, cmp_2);
    	int j = l;
    	for(RG int i = mid + 1; i <= r; i++)
    	{
    		while(j <= mid && a[id[j]] <= down[id[i]]) add(up[id[j]], f[id[j]]), j++;
    		f[id[i]] = max(f[id[i]], query(a[id[i]]) + 1);
    	}
    	for(RG int i = l; i < j; i++) clean(up[id[i]]);
    	Div(mid + 1, r);
    }
    
    int main()
    {
    	n = read(), m = read();
    	for(RG int i = 1; i <= n; i++) up[i] = down[i] = a[i] = read();
    	for(RG int i = 1, x, y; i <= m; i++)
    		x = read(), y = read(),
    		  up[x] = max(up[x], y),
    		  down[x] = std::min(down[x], y);
    	Max = *std::max_element(up + 1, up + n + 1);
    	Div(1, n); printf("%d
    ", *std::max_element(f + 1, f + n + 1));
    	return 0;
    }
    
  • 相关阅读:
    CF763C Timofey and Remoduling
    CF762E Radio Stations
    CF762D Maximum Path
    CF763B Timofey and Rectangles
    URAL1696 Salary for Robots
    uva10884 Persephone
    LA4273 Post Offices
    SCU3037 Painting the Balls
    poj3375 Network Connection
    Golang zip压缩文件读写操作
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10247095.html
Copyright © 2011-2022 走看看