zoukankan      html  css  js  c++  java
  • Codeforces 1175F 尺取法 性质分析

    题意:给你一个数组,问有多少个区间,满足区间中的数构成一个排列。

    思路(大佬代码):我们发现,一个排列一定含有1,所以我们不妨从1开始入手计算构成排列的区间个数。对于每个扫描到的1(假设处于位置i),我们向左右分别延伸,直到遇到1或者到了数组边界,延伸的时候,需要处理下左边到i的最大值和右边到i的最大值。处理之后,我们先处理排列的最大值在左端的情况。我们暴力枚举每一个位置,把它作为区间的左端点(L),现在我们去确认右端点(R),首先,右端点必须大于等于i,因为要包含1。我们先让右端点向左移,因为右端点的mx值不能大于等于左端点的,不然相当于mx值出现了两次。并且R - L + 1必须小于等于mx[L],因为mx[L]是当前排列的最大值,也是排列的长度。之后,因为R - L + 1可能小于mx[L],我们需要增大R,直到长度满足要求,或者下一个数已经在L到R之间出现过了。此时,如果长度满足要求,那么就找到了一个符合要求的排列,答案+1。最大值在右端同理。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 300010;
    int in_LR[maxn];//in_LR == tot :在L,R之间 
    int a[maxn], mx[maxn];
    int main() {
    	int n, tot = 0, L, R, ans = 0;
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &a[i]);
    	}
    	for (int i = 1; i <= n; i++) {
    		if(a[i] != 1) continue;
    		mx[i] = 1;
    		for (int j = i - 1; a[j] != 1 && j >= 1; j--)
    			mx[j] = max(mx[j + 1], a[j]);
    		for (int j = i + 1; j <= n && a[j] != 1; j++)
    			mx[j] = max(mx[j - 1], a[j]);
    		//处理最大值在左半边的情况
    		tot++;
    		L = i, R = i;
    		while(in_LR[a[L]] != tot && L >= 1) {
    			in_LR[a[L]] = tot;//放入R和L之间 
    			L--;
    		}
    		for (L++; L <= i; in_LR[a[L++]] = tot - 1) {
    			while(R > i && (R - L + 1 > mx[L] || mx[R] >= mx[L])) 
    				in_LR[a[R--]] = tot - 1;
    			while(R < n && R - L + 1 < mx[L]) {
    				if(in_LR[a[R + 1]] == tot || a[R + 1] >= mx[L]) break;
    				in_LR[a[++R]] = tot;
    			}
    			if(R - L + 1 == mx[L]) ans++;
    		}
    		//处理最大值在右半边的情况
    		tot++;
    		L = i, R = i;
    		while(in_LR[a[R]] != tot && R <= n) {
    			in_LR[a[R]] = tot;//放入R和L之间 
    			R++;
    		}
    		for (R--; R > i; in_LR[a[R--]] = tot - 1) {
    			while(L < i && (R - L + 1 > mx[R] || mx[L] >= mx[R])) 
    				in_LR[a[L++]] = tot - 1;
    			while(L > 1 && R - L + 1 < mx[R]) {
    				if(in_LR[a[L - 1]] == tot || a[L - 1] >= mx[R]) break;
    				in_LR[a[--L]] = tot;
    			}
    			if(R - L + 1 == mx[R]) ans++;
    		}
    	}
    	printf("%d
    ", ans);
    }
    

      

  • 相关阅读:
    zBrow发布倒计时:对不起,让大家久等了
    《zBrow的资本论》
    zBrow智能浏览器
    zspt界面截图
    电商领域,唯一的“发明”级国家专利。
    zBrow界面截图截图
    zBrow多开界面截图
    网页滚动条样式
    关于margin参数解读
    JAVA的抽象类和抽象方法
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/10987079.html
Copyright © 2011-2022 走看看