zoukankan      html  css  js  c++  java
  • 铅 单调栈例题

    关于学习

    看洛谷网校学习的

    单调栈例题

    例题:

    • [x] P2947 [USACO09MAR]向右看齐Look Up
    • [x] POJ3250 Bad Hair Day
    • [x] POJ2796Feel Good
    • [x] POJ2559Largest Rectangle in a Histogram
    • [x] BZOJ 1345: [Baltic2007]序列问题Sequence
    • [x] BZOJ4750: 密码安全
    • [x] BZOJ3039: 玉蟾宫
    • [ ] 【uoj#213】[UNR #1]争夺圣杯

    Solution:

    T1:向右看齐Look Up 单调栈裸题
    T2:POJ3250 Bad Hair Day 单调栈裸题
    T3:考虑第i位为最小值来更新答案,用单调栈维护出左边第一个大于他的位置,和右边第一个大于他的位置即可。
    T4:先贪心考虑以第i个矩形为基础的矩形有多大,然后用单调栈维护即可。
    T5:在最优策略下,非最大值的数,一定是与它左右第一个比它大的数中较小的那个替代的。
    T6:考虑第i位是最小值,然后二进制拆位计算方案数。
    T7:考虑枚举每一点,然后每一点横向能扩展到哪里,然后跟T4差不多了
    T8:不会
    把一些难写的题放上来吧。

    BZOJ 1345: [Baltic2007]序列问题Sequence

    int a[maxN], b[maxN], c[maxN];
    int sta[maxN] , top;
    
    int main() {
    	int n = gi();
    	a[0] = INF;a[n + 1] = INF;
    	for(int i = 1;i <= n;++ i) a[i] = gi();
    	for(int i = n;i >= 1;-- i) {
    		while(top && a[sta[top]] < a[i]) {
    			b[sta[top --]] = i;
    		}
    		sta[++ top] = i;
    	}
    	for(int i = 1;i <= n;++ i) {
    		while(top && a[sta[top]] <= a[i]) {
    			c[sta[top --]] = i;
    		}
    		sta[++ top] = i;
    	}
    	ll ans = 0;
    	for(int i = 1;i <= n;++ i) {
    		int x = min(a[b[i]] , a[c[i]]);
    		if(x != INF) ans += x;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
    int a[maxN], b[maxN], c[maxN];
    int sta[maxN] , top;
    
    int main() {
    	int n = gi();
    	a[0] = INF;a[n + 1] = INF;
    	for(int i = 1;i <= n;++ i) a[i] = gi();
    	for(int i = n;i >= 1;-- i) {
    		while(top && a[sta[top]] < a[i]) {
    			b[sta[top --]] = i;
    		}
    		sta[++ top] = i;
    	}
    	top = 0;
    	for(int i = 1;i <= n;++ i) {
    		while(top && a[sta[top]] <= a[i]) {
    			c[sta[top --]] = i;
    		}
    		sta[++ top] = i;
    	}
    	ll ans = 0;
    	for(int i = 1;i <= n;++ i) {
    		int x = min(a[b[i]] , a[c[i]]);
    		if(x != INF) ans += x;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

    BZOJ4750: 密码安全

    int a[N] , sum[N] , c[N][30] , lp[N] , rp[N] , sta[N] , tot;
    int main() {
        int T;
        scanf("%d" , &T);
        while(T -- ) {
            int n , i , j , ans = 0;
            scanf("%d" , &n);
            memset(c , 0 , sizeof(c));
            for(i = 2 ; i <= n + 1 ; i ++ ) {
                scanf("%d" , &a[i]) , sum[i] = sum[i - 1] ^ a[i];
                for(j = 0 ; j < 30 ; j ++ ) c[i][j] = c[i - 1][j] + (bool)(sum[i] & (1 << j));
            }
            tot = 0 , sta[0] = 1;
            for(i = 2 ; i <= n + 1 ; i ++ ) {
                while(tot && a[sta[tot]] < a[i]) tot -- ;
                lp[i] = sta[tot] , sta[++ tot] = i;
            }
            tot = 0 , sta[0] = n + 2;
            for(i = n + 1 ; i >= 2 ; i -- ) {
                while(tot && a[sta[tot]] <= a[i]) tot -- ;
                rp[i] = sta[tot] , sta[++tot] = i;
            }
            for(i = 2 ; i <= n + 1 ; i ++ )
                for(j = 0 ; j < 30 ; j ++ )
                    ans = (ans + ((ll)(c[i - 1][j] - c[lp[i] - 1][j]) * (rp[i] - i - c[rp[i] - 1][j] + c[i - 1][j])
                               + (ll)(i - lp[i] - c[i - 1][j] + c[lp[i] - 1][j]) * (c[rp[i] - 1][j] - c[i - 1][j])) % mod
                               * (1 << j) % mod * a[i]) % mod;
            printf("%d
    " , ans);
        }
        return 0;
    }
    

    Largest Rectangle in a Histogram

    BZOJ3039: 玉蟾宫

    using namespace std;
    int a[N][N] , sta[N] , tot , lp[N] , rp[N];
    char str[5];
    int main() {
    	int n , m , i , j , ans = 0;
    	scanf("%d%d" , &n , &m);
    	for(i = 1 ; i <= n ; i ++ ) {
    		for(j = 1 ; j <= m ; j ++ ) {
    			scanf("%s" , str);
    			if(str[0] == 'F')
    				a[i][j] = a[i - 1][j] + 1;
    		}
    		tot = 0 , sta[0] = 0;
    		for(j = 1 ; j <= m ; j ++ ) {
    			while(tot && a[i][j] <= a[i][sta[tot]]) tot -- ;
    			lp[j] = sta[tot] , sta[++tot] = j;
    		}
    		tot = 0 , sta[tot] = m + 1;
    		for(j = m ; j ; j -- ) {
    			while(tot && a[i][j] <= a[i][sta[tot]]) tot -- ;
    			rp[j] = sta[tot] , sta[++tot] = j;
    		}
    		for(j = 1 ; j <= m ; j ++ ) ans = max(ans , a[i][j] * (rp[j] - lp[j] - 1));
    	}
    	printf("%d
    " , ans * 3);
    	return 0;
    }
    
    
  • 相关阅读:
    [ solr入门 ] 在schema.xml中加入自己的分词工具
    SQLServer2005获取大数据集时内存不足的解决办法[转]
    java位操作基本教程[转]
    log4j的最佳实践(转)
    [ lucene扩展 ] "Did you mean" feature with Apache Lucene SpellChecker
    java image filters[02]过滤器初探
    PHP serialize 和 JSON 解析与区别
    js 实现 静态缓存页面中访问动态IP下载地址
    smarty section foreach遍历多维数组
    【转】window.open 参数
  • 原文地址:https://www.cnblogs.com/gaozhuoyuan/p/11711865.html
Copyright © 2011-2022 走看看