zoukankan      html  css  js  c++  java
  • P4093 [HEOI2016/TJOI2016]序列

    这个题n^2暴力显然,然后考虑优化,每次找前面的最大值,有点像是三维偏序,树套树和cdq都能做,这里用cdq,sort的cdq好像比较简单。。。

    题干:

    题目描述
    
    佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他。玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一个值发生变化。现在佳媛姐姐已经研究出了所有变化的可能性,她想请教你,能否选出一个子序列,使得在任意一种变化中,这个子序列都是不降的?请你告诉她这个子序列的最长长度即可 。
    
    注意:每种变化最多只有一个值发生变化。在样例输入1中,所有的变化是:
    
    1 2 3 
    2 2 3 
    1 3 3 
    1 1 3
    1 2 4 
    
    选择子序列为原序列,即在任意一种变化中均为不降子序列在样例输入2中,所有的变化是:
    
    3 3 3
    3 2 3
    
    选择子序列为第一个元素和第三个元素,或者第二个元素和第三个元素,均可满足要
    输入输出格式
    输入格式:
    
    输入的第一行有两个正整数n, m,分别表示序列的长度和变化的个数。接下来一行有n个数,表示这个数列原始的状态。接下来m行,每行有2个数x, y,表示数列的第x项可以变化成y这个值。1 <= x <= n。
    
    输出格式:
    
    输出一个整数,表示对应的答案

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<vector>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;++i)
    #define lv(i,a,n) for(register int i = a;i >= n;--i)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    #define N 100010
    int n,m;
    int a[N];
    int minc[N],maxc[N];
    int id[N],dp[N],tree[N];
    int lowbit(int x)
    {
        return x & -x;
    }
    void insert(int pos,int x)
    {
        for(;pos <= 100000;pos += lowbit(pos))
        tree[pos] = max(tree[pos],x);
    }
    int query(int pos)
    {
        int ans = 0;
        for(;pos;pos -= lowbit(pos))
        ans = max(tree[pos],ans);
        return ans;
    }
    void erase(int pos)
    {
        for(;pos <= 100000;pos += lowbit(pos))
        {
            tree[pos] = 0;
        }
    }
    int Max(int l,int r)
    {
        int maxn = 0;
        duke(i,l,r)
        {
            maxn = max(maxn,dp[i]);
        }
        return maxn;
    }
    void cdq(int l,int r)
    {
        if(l == r)
        {
            dp[l] = max(dp[l],1);
            return;
        }
        int mid = (l + r) >> 1;
        cdq(l,mid);
        static int oid[N];
        duke(i,l,r)
        oid[i] = id[i];
        sort(id + l,id + mid + 1,[](int x,int y){return maxc[x] < maxc[y];});
        sort(id + mid + 1,id + r + 1,[](int x,int y){return a[x] < a[y];});
        static vector <int> todel;
        int p1 = l;
        for(int p2 = mid + 1;p2 <= r;p2++)
        {
            while(p1 <= mid && maxc[id[p1]] <= a[id[p2]])
            {
                insert(a[id[p1]],dp[id[p1]]);
                todel.push_back(a[id[p1]]);
                ++p1;
            }
            int tans = query(minc[id[p2]]) + 1;
            dp[id[p2]] = max(dp[id[p2]],tans);
        }
        while(!todel.empty())
        {
            erase(todel.back());
            todel.pop_back();
        }
        duke(i,l,r)
        id[i] = oid[i];
        cdq(mid + 1,r);
    }
    int main()
    {
        read(n);read(m);
        duke(i,1,n)
        {
            read(a[i]);
            minc[i] = maxc[i] = a[i];
            id[i] = i;
        }
        duke(i,1,m)
        {
            int pos,x;
            read(pos);read(x);
            minc[pos] = min(minc[pos],x);
            maxc[pos] = max(maxc[pos],x);
        }
        cdq(1,n);
        int ans = Max(1,n);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    【leetcode】1630. Arithmetic Subarrays
    【leetcode】1629. Slowest Key
    【leetcode】1624. Largest Substring Between Two Equal Characters
    【leetcode】1620. Coordinate With Maximum Network Quality
    【leetcode】1619. Mean of Array After Removing Some Elements
    【leetcode】1609. Even Odd Tree
    【leetcode】1608. Special Array With X Elements Greater Than or Equal X
    【leetcode】1603. Design Parking System
    【leetcode】1598. Crawler Log Folder
    Java基础加强总结(三)——代理(Proxy)Java实现Ip代理池
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10527018.html
Copyright © 2011-2022 走看看