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); } }