• 1167E (尺取法)


    http://codeforces.com/problemset/problem/1167/E

    题意:

    删除一个区间f(l, r)后使剩下的数不递减, 求这样区间的个数

    因为一个数可以在这个数组中出现多次,所以转化为,先预处理出所有数的最左边的下标和最右边的下标,这样每个数都有一个区间

    然后求最多有多少个f(l, r)使剩下的数的左右区间不相交

    解析:

    先从后向前求出一个递减的序列,如果当前数r的区间扰乱了这个递减的序列,那么f(1,r)、 f(1, r + 1)······f(1, x)都符合要求 所以就有x - r + 1个

    然后我们定r,缩l判断f(2, r)是否符合要求,如果不符合则r向后累加

    当然首先要保证1的区间和2的区间,是递增的 如果不递增,输出结果即可,自己想一想为什么

     

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1001000, INF = 0x7fffffff;
    typedef long long LL;
    LL l[maxn], r[maxn];
    LL vis[maxn];
    
    struct node
    {
        LL succ;
    }Node[maxn];
    
    
    int main()
    {
        LL n, x;
        cin >> n >> x;
        for(int i = 1; i <= x; i++) l[i] = INF;
    
        for(LL i = 1; i <= n; i++)
        {
            LL tmp;
            cin >> tmp;
            Node[tmp].succ = tmp;
            vis[tmp] = 1;
            l[tmp] = min(l[tmp], i);
            r[tmp] = i;
        }
        LL pre, succ;
        for(int i = 1; i <= x; i++)
        {
            if(vis[i] == 0)
            {
                if(i == 1) r[i] = 1, succ = i;
                else r[i] = pre, Node[i].succ = succ;
            }
            if(vis[i]) succ = i;
            pre = r[i];
        }
    
        for(int i = x; i >= 1; i--)
        {
            if(vis[i] == 0)
            {
                if(i == x) l[i] = n;
                else l[i] = pre;
            }
            pre = l[i];
        }
        int pos = -1;
        for(int i = x; i >= 2; i--)
        {
            if(r[i - 1] > l[i])
            {
                pos = Node[i - 1].succ;
                break;
            }
        }
        if(pos == -1)
        {
            LL ret = (LL)(x * (x + 1) / 2);
            printf("%lld
    ", ret);
            return 0;
    
        }
        LL res = 0;
        res += x - pos + 1;
      //  cout << res << endl;
        for(int i = 1; i <= x; i++)
        {
            if(l[i] < r[i - 1] && vis[i] != 0) break;
    
            while(pos <= x - 1 && r[i] > l[pos + 1]) pos++;
            res += x - pos + 1;
    
        }
        cout << res << endl;
    
    
        return 0;
    }

     

  • 相关阅读:
    Minimum Path Sum,最短路径问题,动态规划
    UniquePaths,UniquePaths2,路径问题。动态规划。
    LengthOfLastWord,字符串最后一个子串的长度
    间隔问题,合并间隔(merge interval),插入间隔(insert interval)
    矩阵螺旋遍历Spiral Matrix,Spiral Matrix2
    Centos 5.2 下配置 php 的 json 扩展
    一个睡五分钟等于六个钟头的方法
    js div 排除内部的点击事件 就是 冒泡的处理
    做微信开发 “人脉圈的” 总结
    YII 学习笔记
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/10912013.html
Copyright © 2020-2023  润新知