• Codeforces Round #305 (Div. 2) D题 (线段树+RMQ)


    D. Mike and Feet
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Mike is the president of country What-The-Fatherland. There are n bears living in this country besides Mike. All of them are standing in a line and they are numbered from 1 to n from left to right. i-th bear is exactly ai feet high.

    A group of bears is a non-empty contiguous segment of the line. The size of a group is the number of bears in that group. The strengthof a group is the minimum height of the bear in that group.

    Mike is a curious to know for each x such that 1 ≤ x ≤ n the maximum strength among all groups of size x.

    Input

    The first line of input contains integer n (1 ≤ n ≤ 2 × 105), the number of bears.

    The second line contains n integers separated by space, a1, a2, ..., an (1 ≤ ai ≤ 109), heights of bears.

    Output

    Print n integers in one line. For each x from 1 to n, print the maximum strength among all groups of size x.

    Sample test(s)
    input
    10
    1 2 3 4 5 4 3 2 1 6
    output
    6 4 4 3 3 2 2 1 1 1 

    先用ST算法处理出一段区间内最小值。二分查询出对于第i个数,以它为最小向左或向右可达的最值,得到区间长度为r-l+1。那么,对于group长度为1,2,3,....r-l+1最小值为第i个数的值。则区间更新这些组大小,取最大值。此处可以使用线段树维护。
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=200050;
    const int inf=1e9+107;
    
    int feet[N];
    int st[N][20];
    int seg[N<<2];
    int ans[N];
    void pushdown(int rt){
    	seg[rt<<1]=max(seg[rt<<1],seg[rt]);
    	seg[rt<<1|1]=max(seg[rt<<1|1],seg[rt]);
    	seg[rt]=-1;
    }
    
    void ST(int num){
    	for(int i=1;i<=num;i++)
    	st[i][0]=feet[i];
        for(int j=1;j<20;j++)
            for(int i=1;i<=num;i++){
                if(i+(1<<j)-1 <= num){
                    st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
                }
            }
    }
    
    void update(int rt,int l,int r,int L,int R,int val){
    	if(l<=L&&R<=r){
    		if(val>seg[rt]) seg[rt]=val; return;
    	}
    	int m=(L+R)>>1;
    	pushdown(rt);
    	if(r<=m){
    		update(rt<<1,l,r,L,m,val);
    	}
    	else if(l>=m+1){
    		update(rt<<1|1,l,r,m+1,R,val);
    	}
    	else{
    		update(rt<<1,l,r,L,m,val);
    		update(rt<<1|1,l,r,m+1,R,val);
    	}
    }
    
    void dfs(int rt,int L,int R){
    	if(L==R){
    		ans[L]=seg[rt];
    		return ;
    	}
    	pushdown(rt);
    	int m=(L+R)>>1;
    	dfs(rt<<1,L,m);
    	dfs(rt<<1|1,m+1,R);
    }
    
    int query(int l,int r){
    	int k=(int)((log(r-l+1))/log(2.0));
        int maxl=min(st[l][k],st[r-(1<<k)+1][k]);
        return maxl;
    }
    
    int main(){
    	int n;
    	while(scanf("%d",&n)!=EOF){
    		for(int i=1;i<=(n<<2)+10;i++){
    			seg[i]=-1;
    		}
    		for(int i=1;i<=n;i++){
    			scanf("%d",&feet[i]);
    		}
    		ST(n); 
    		for(int i=1;i<=n;i++){
    			//left
    			int l=1,r=i;
    			int L=i,R=i;
    			while(l<=r){
    				int m=(l+r)>>1;
    				int index=query(m,i);
    				if(index>=feet[i]){
    					r=m-1;
    					L=m;
    				}
    				else {
    					l=m+1;
    				}
    			}
    			//right
    			l=i,r=n;
    			while(l<=r){
    				int m=(l+r)>>1;
    				int index=query(i,m);
    				if(index>=feet[i]){
    					l=m+1;
    					R=m;
    				}
    				else {
    					r=m-1;
    				}
    			}
    			update(1,1,R-L+1,1,n,feet[i]);
    		}
    		dfs(1,1,n);
    		printf("%d",ans[1]);
    		for(int i=2;i<=n;i++)
    		printf(" %d",ans[i]);
    		printf("
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    hdu5926Mr. Frog’s Game
    hdu5926Mr. Frog’s Game
    hdu5924Mr. Frog’s Problem
    hdu5924Mr. Frog’s Problem
    hdu5922Minimum’s Revenge
    hdu5922Minimum’s Revenge
    带空格的字符串输入
    带空格的字符串输入
    382. Linked List Random Node
    319. Bulb Switcher
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4536967.html
Copyright © 2020-2023  润新知