zoukankan      html  css  js  c++  java
  • HDU 3410 Passing the Message

    可以先处理出每个a[i]最左和最右能到达的位置,L[i],和R[i]。然后就只要询问区间[ L[i],i-1 ]和区间[ i+1,R[i] ]最大值位置即可。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-8;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    inline int read()
    {
        char c = getchar();  while(!isdigit(c)) c = getchar();
        int x = 0;
        while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
        return x;
    }
    
    const int maxn=50000+10;
    int T,n,a[maxn],L[maxn],R[maxn],dp[maxn][30];
    
    void RMQ_init()
    {
        for(int i=0;i<n;i++) dp[i][0]=i;
        for(int j=1;(1<<j)<=n;j++)
            for(int i=0;i+(1<<j)-1<n;i++)
            {
                if(a[dp[i][j-1]]>a[dp[i+(1<<(j-1))][j-1]]) dp[i][j]=dp[i][j-1];
                else dp[i][j]=dp[i+(1<<(j-1))][j-1];
            }
    }
    
    int RMQ(int L,int R)
    {
        int k=0;
        while((1<<(k+1))<=R-L+1) k++;
        if(a[dp[L][k]]>a[dp[R-(1<<k)+1][k]]) return dp[L][k];
        return dp[R-(1<<k)+1][k];
    }
    
    int main()
    {
        scanf("%d",&T); int cas=1;
        while(T--)
        {
            scanf("%d",&n);
            for(int i=0;i<n;i++) scanf("%d",&a[i]), L[i]=R[i]=i;
            for(int i=1;i<n;i++)
            {
                if(a[i]<a[i-1]) continue; int pre=L[i-1];
                while(1) { L[i]=pre; if(pre==0||a[pre-1]>a[i]) break; pre=L[pre-1]; }
            }
            for(int i=n;i>=1;i--) R[i]=i;
            for(int i=n-2;i>=0;i--)
            {
                if(a[i]<a[i+1]) continue; int pre=R[i+1];
                while(1) { R[i]=pre; if(pre==n-1||a[pre+1]>a[i]) break; pre=R[pre+1]; }
            }
    
            RMQ_init();
            printf("Case %d:
    ",cas++);
            for(int i=0;i<n;i++)
            {
                if(L[i]>i-1) printf("0 "); else printf("%d ",RMQ(L[i],i-1)+1);
                if(R[i]<i+1) printf("0
    "); else printf("%d
    ",RMQ(i+1,R[i])+1);
            }
        }
        return 0;
    }
  • 相关阅读:
    js 高阶函数之柯里化
    JavaScript 相关的工具代码
    JS 数组、对象的深拷贝
    页面性能优化
    axios(封装使用、拦截特定请求、判断所有请求加载完毕)
    java 实现登录验证码 (kaptcha 验证码组件)
    告别 hash 路由,迎接 history 路由
    解决 Vue 动态生成 el-checkbox 点击无法赋值问题
    分享基于 websocket 网页端聊天室
    vue + element 动态渲染、移除表单并添加验证
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5740703.html
Copyright © 2011-2022 走看看