• Codeforces 1167E 尺取法


    题意:给你一个长度为n的数组,以及数组中的数的取值范围1 - m,问有多少个区间[l, r],使得删除了数组中数值为[l, r]的数之后,数组是非递减的。

    思路:我们记录一下每一个数出现的最左端和最右端的位置,这样形成的若干个区间,如果数组是非递减的,那么一定是下列这种情况:范围1 - n中有若干个不相交的区间,并且区间所代表的数从左到右是递增的。所以我们想到如下算法:我们先预处理出从最右端一直向左可以找出多少个数所代表的区间不相交,然后枚举从最左端添加区间,先保证左右没有相交,然后计算答案,如果左边出现了相交的情况就break,因为后面肯定不满足答案了。

    代码:

    #include <bits/stdc++.h>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define db double
    #define pii pair<int, int>
    using namespace std;
    const int maxn = 1000010;
    int l[maxn], r[maxn];
    int b[maxn];
    LL cnt[maxn];
    int main() {
    	LL n, m;
    	scanf("%lld%lld", &n ,&m);
    	memset(l, 0x3f, sizeof(l));
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &b[i]);
    		l[b[i]] = min(l[b[i]], i);
    		r[b[i]] = max(r[b[i]], i);
    		cnt[b[i]]++;
    	}
    	LL L = n + 1, R = -1, pos = -1;
    	LL tot = 0, ans = 0;
    	for (int i = m; i >= 1; i--) {
    		if(cnt[i] == 0) {
    			l[i] = l[i + 1];
    			continue;
    		}
    		if(r[i] < L) {
    			L = l[i];
    		} else {
    			tot = m - i + 1;
    			pos = i + 1;
    			break;
    		}
    	}
    	if(pos == -1) {
    		ans = (m * (m + 1)) / 2;
    		printf("%lld
    ", ans);
    		return 0;
    	}
    	for (int i = 0; i <= m; i++) {
    		if(cnt[i] == 0) {
    			ans += tot;
    			continue;
    		}
    		if(l[i] < R) {
    			break;
    		} else {
    			if(cnt[i] == 0) r[i] = r[i - 1];
    			R = r[i];
    			while(L <= R && pos <= m) {
    				if(cnt[pos] == 0) {
    					tot--;
    					pos++;
    					L = l[pos];
    				} else {
    					pos++;
    					tot--;
    					L = l[pos];
    				}
    			}
    			ans += tot;
    		}
    	}
    	printf("%lld
    ", ans);
    	return 0;
    } 
    

      

  • 相关阅读:
    洛谷 P1219 八皇后【经典DFS,温习搜索】
    洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
    hihoCoder #1015 : KMP算法【KMP裸题,板子】
    UVa 10341
    UVa 11461
    Uva
    BZOJ 3097: Hash Killer I【构造题,思维题】
    BZOJ 1207: [HNOI2004]打鼹鼠【妥妥的n^2爆搜,dp】
    BZOJ 1800: [Ahoi2009]fly 飞行棋【思维题,n^4大暴力】
    新版百度指数2013-12-23正式上线
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/10877539.html
Copyright © 2020-2023  润新知