hdu5358

1.因为num[i]中存的是1到i的数的和,所以设成了long long int,但是,输入时,因为想着都是int能存储的,所以照样用的是%d,但是事实证明,这样是不可以的,既然是long long int,就必须用long long int,否则一直wr。

2.memset也挺费时间的,加一个memset,就直接t了。

代码参考:http://blog.csdn.net/firenet1/article/details/47321147

(牛肉馅包子难道不是意味着包子里有很多牛肉吗,为什么变成了,包子只是有牛肉的味道,却几乎没有肉呢?大部分都是洋葱!才短短两天,包子怎么就变了呢?沧海桑田呀,是不是厨师因为停水两天在报复社会呢?如果在土豆泥丸子里加上鱼肉馅,炸完后沾上番茄酱,是不是会很好吃呢?)

2015.8.29:

感觉num里如果存的不是和,而是每个数,其实也不会超时(只是感觉,还没有尝试,原谅一个时间复杂度不会算并且比较懒的人),dp[i][j]里一开始想的是存从i开始,长度为j的,严格为j的,后来发现算起来可能有些麻烦,如果当成长度不超过j位的就会省事很多。总之,就是不能太死板,能偷懒就偷懒。

(话说,奇葩说第一季真的很欢乐大笑

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 100010

long long int num[N];
long long int dp[N][40];

int main(){
    int t;
    int n;

    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        num[0]=0;
        for(int i=1;i<=n;i++){
            scanf("%lld",&num[i]);
            num[i]=num[i]+num[i-1];
        }
        for(int i=0;i<=34;i++){
            long long int temp=(long long int)1<<i;
            int p=1;

            for(int j=1;j<=n;j++){
                while((num[p]-num[j-1]<temp)&&(p<n)){
                    p++;
                }

                if(num[p]-num[j-1]<temp){
                    dp[j][i]=p;
                }
                else{
                    dp[j][i]=p-1;
                }

                //printf("%d %d %d\n",j,i,dp[j][i]);
            }
        }


        long long int ans=0;
        for(int i=1;i<=n;i++){
            ans+=(dp[i][0]-i+1)*i+(i+dp[i][0])*(dp[i][0]-i+1)/2;

            for(int j=1;j<=34;j++){
                long long int temp=j*((dp[i][j]-dp[i][j-1])*i+(dp[i][j-1]+1+dp[i][j])*(dp[i][j]-dp[i][j-1])/2);
                ans+=temp;
                //printf("%d %d %lld\n",i,j,temp);
            }
        }

        printf("%lld\n",ans);
    }
}


posted @ 2015-08-15 08:38  buzhidaohahaha  阅读(234)  评论(0编辑  收藏  举报