zoukankan      html  css  js  c++  java
  • hdu-5358 First One(尺取法)

    题目链接:

    First One

    Time Limit: 4000/2000 MS (Java/Others)    

    Memory Limit: 131072/131072 K (Java/Others)


    Problem Description
     
    soda has an integer array a1,a2,,an. Let S(i,j) be the sum of ai,ai+1,,aj. Now soda wants to know the value below:
    i=1nj=in(log2S(i,j)+1)×(i+j)

    Note: In this problem, you can consider log20 as 0.
     
    Input
     
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    The first line contains an integer n (1n105), the number of integers in the array.
    The next line contains n integers a1,a2,,an (0ai105).
     
    Output
     
    For each test case, output the value.
     
    Sample Input
     
    1
    2
    1 1
     
    Sample Output
     
    12
     
    题意:
     
    求这个sum啦啦啦;
     
    思路:
     
    还是得用尺取法,我二分找两个端点,tle了,看来常数卡的好紧啊啊啊;
     
     
    AC代码:
     
    /*    5358    1638MS    3120K    1119 B    G++    2014300227*/
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+4;
    typedef long long ll;
    int n;
    ll a[N],sum[N];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%lld",&a[i]);
            }
            sum[0]=0;
            a[n+1]=0;
            for(int i=1;i<=n+1;i++)
            {
                sum[i]=sum[i-1]+a[i];
            }
            ll ans=0,num=0;
            ll L=0,R=1,len;
            for(int i=0;i<=33;i++)
            {
                num=0;
                int l=1,r=1;
                for(int j=1;j<=n;j++)//左端点为j,l和r为右端点可取的区间;并不是l表示左端点,r表示右端点;所以复杂度才降了下来;
                {
                    l=max(j,l);
                    while(l<=n&&sum[l]-sum[j-1]<L)l++;
                    r=max(r,l);
                    while(r<=n&&sum[r]-sum[j-1]<=R&&sum[r]-sum[j-1]>=L)r++;
                    len=r-l;
                    num+=len*(ll)j+len*(l+r-1)/2;
                }
                L=R+1;
                R=2*L-1;
                ans+=num*(ll)(i+1);
            }
    
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Java中只有按值传递,没有按引用传递!(两种参数情况下都是值传递)
    最简单的struts实例介绍
    Spring中bean的五个作用域简介(转载)
    Spring配置文件
    轻松搞定面试中的二叉树题目 (转)
    二叉树
    稳定排序与非稳定排序判别方法
    Yii的缓存机制之动态缓存
    Yii的缓存机制之数据缓存
    Yii的缓存机制之页面缓存
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5393720.html
Copyright © 2011-2022 走看看