zoukankan      html  css  js  c++  java
  • 2016"百度之星"

    1001 区间的价值:

       RMQ+扫描法

      我们预处理RMQ求任意区间的最大值

      预处理出以a[i]为最小值 能向左延伸 向右延伸的 L[i], R[i]

      那么对于 一个答案 (L[i], R[i]) *rmq(L[i],R[i]) 为此长度的答案,我们可以发现他是可以更新到小于其长度的所有长度答案的,更新就好

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include<map>
    using namespace std;
    const int N = 1e5+10, M = 30005, mod = 1e9 + 7, inf = 0x3f3f3f3f;
    typedef long long ll;
    ll a[N],dp[N][30],ans[N],las[N];
    int l[N],r[N],n;
    void RMQ_init() {
        memset(dp,0,sizeof(dp));
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        for(int i=1;i<=n;i++) dp[i][0] = a[i];
        for(int j=1;(1<<j)<=n;j++) {
            for(int i=1;i + (1<<j) - 1 <= n; i++) {
                if(dp[i][j-1] > 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];
                }
            }
        }
         l[1] = 1;a[0] = -1000;a[n+1] = -10000;
        for(int i=2;i<=n;i++) {
            int tmp = i-1;
            while(a[i]<=a[tmp]) tmp = l[tmp]-1;
            l[i] = tmp+1;
        }
        r[n] = n;
        for(int i=n-1;i>=1;i--) {
             int tmp = i+1;
            while(a[i]<=a[tmp]) tmp = r[tmp] + 1;
            r[i] = tmp - 1;
        }
    }
    ll rmq(int l,int r) {
        if(l==r) return a[l];
        int k = (int) (log((double) r-l+1) / log(2.0));
        return max(dp[l][k], dp[r - (1<<k) + 1][k]);
    }
    int main() {
        while(scanf("%d",&n)!=EOF) {
            for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
            RMQ_init();
            for(int i=1;i<=n;i++) ans[i] = -1;
            for(int i=1;i<=n;i++) {
                ll mm = rmq(l[i],r[i]);
                ans[r[i]-l[i]+1] = max(mm*a[i],ans[r[i]-l[i]+1]);
            }
            las[n+1] = -1;
            for(int i=n;i>=1;i--) {
                las[i] = max(ans[i],las[i+1]);
            }
            for(int i=1;i<=n;i++) printf("%I64d
    ",las[i]);
        }
        return 0;
    }
    View Code

    1003 瞬间移动:

      组合数学

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<stack>
    #include<map>
    #define ll __int64
    #define mod 1000000007
    using namespace std;
    ll poww(ll a,ll n)
    {
       ll r=1,p=a;
       while(n)
       {
           if(n&1) r=(r*p)%mod;
           n>>=1;
           p=(p*p)%mod;
       }
       return r;
    }
    ll coun(ll n,ll m) 
    {
        ll sum=1; 
        for(ll i=1,j=n;i<=m;i++,j--)
        {
            sum*=j;
            sum%=mod;
            sum*=poww(i,1000000005);
            sum%=mod;
        }
        return sum;
    }
     ll x,y,z,t; 
     ll n,k;
     ll ans;
    int main()
    {
        while(scanf("%I64d %I64d",&x,&y)!=EOF)
        {
            ans=0;
            n=(x+y)-4;
            k=x-2;
            ans=coun(n,k);
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    1006 中位数计数

      我也不知道分类

      枚举以a[i]为中位数, 重构一个数组,小于a[i]的是-1,大于a[i]的是1,等于a[i]是0;,

      这个问题就变成了求这个数组有多少个区间包含0,且区间和是0的个数,这个用前缀解决

      map超时

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include<queue>
    #include<map>
    using namespace std;
    const int N = 1e5+20, M = 1e4, mod = 1000000007,inf = 1e9;
    typedef long long ll;
    
    int a[N],b[N],n,now[N];
    int H[N];
    ll ans[N];
    int  f[N],h[N];
    
    int main() {
        while(scanf("%d",&n)!=EOF) {
            for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i] = a[i];
            for(int i=1;i<=n;i+=1) {
    
                memset(f,0,sizeof(f));
                memset(h,0,sizeof(h));
    
                for(int j=1;j<=n;j++)
                if(a[i]==a[j]) now[j] = 0;
                else if(a[i]>a[j]) now[j] = 1;
                else if(a[i]<a[j]) now[j] = -1;
    
               int last = 0,mx = 0;
               ll aa = 1;
                for(int j=i-1;j>=1;j--) f[last+now[j]+M]++,last +=now[j],mx = max(mx,last);
                last = 0;
                for(int j=i+1;j<=n;j++) h[last+now[j]+M]++,last +=now[j],mx = max(mx,last);
                for(int j=1;j<=mx;j++) aa += ((ll)f[j+M]*(ll)h[-j+M]),aa+=((ll)f[-j+M]*(ll)h[j+M]);
                aa+=f[0+M];
                aa+=h[0+M];
                aa+=(ll)f[0+M]*(ll)h[0+M];
                ans[i] = aa;
            }
            for(int i=1;i<n;i+=1) {
                printf("%I64d ",ans[i]);
            }
            printf("%I64d
    ",ans[n]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    VSCode打开大文件插件
    https Java SSL Exception protocol_version
    Error creating bean with name 'tomcatEmbeddedServletContainerFactory ' (or a BeanPostProcessor involved) returned null
    在Java8的foreach()中不能break,如果需要continue时,可以使用return
    Spring cloud 超时及重试配置【ribbon及其它http client】
    祸害阿里云宕机 3 小时的 IO HANG 究竟是个什么鬼?!
    Convertion of grey code and binary 格雷码和二进制数之间的转换
    stringstream 使用方法
    [LeetCode] 91. Decode Ways 解码方法
    QString, string, int, char* 之间相互转换
  • 原文地址:https://www.cnblogs.com/zxhl/p/5517112.html
Copyright © 2011-2022 走看看