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;
    }
    
    
  • 相关阅读:
    Oracle函数如何把符串装换为小写的格式
    Oralce中的synonym同义词
    JS中getYear()的兼容问题
    How to do SSH Tunneling (Port Forwarding)
    所谓深度链接(Deep linking)
    upload size of asp.net
    发一个自动刷网站PV流量的小工具
    解决Visual Studio 2008 下,打开.dbml(LINQ) 文件时,提示"The operation could not be completed." 的问题。
    在资源管理器中使鼠标右键增加一个命令,运行cmd,同时使得当前路径为资源管理器当前的目录
    使用SQL语句获取Sql Server数据库的版本
  • 原文地址:https://www.cnblogs.com/gaozhuoyuan/p/11711865.html
Copyright © 2011-2022 走看看