这道题看出来了是一道STL题,本来一开始用队列去做,结果TLE,在这里先给出TLE代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int n,V[maxn],T[maxn];
int main()
{
while(scanf("%d",&n)==1)
{
for(int i=0;i<n;i++) scanf("%d",&V[i]);
for(int i=0;i<n;i++) scanf("%d",&T[i]);
queue<int > que;
for(int i=0;i<n;i++)
{
que.push(V[i]);
ll cnt=0;
int len=que.size();
for(int j=0;j<len;j++)
{
int vi=que.front(); que.pop();
if(vi>T[i])
{
cnt+=T[i];
que.push(vi-T[i]);
}
else cnt+=vi;
}
if(i) printf(" ");
printf("%lld",cnt);
}
printf("\n");
}
return 0;
}
原因是,第二个循环逐个去统计维护,会消耗大量时间,但是思路比较简单
比赛完后看了其他大佬的代码发现都是用优先队列做的,而且在统计方面也是很精炼,大家可以多注意一下,下面代码在计数方面的技巧:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int n,V[maxn],T[maxn];
int main()
{
scanf("%d",&n);
for(int i=0; i<n; i++) scanf("%d",&V[i]);
for(int i=0; i<n; i++) scanf("%d",&T[i]);
priority_queue<ll,vector<ll>,greater<ll> > que;
ll sum=0;
for(int i=0; i<n; i++)
{
que.push(V[i]+sum);// 每次都加上sum是为了防止以前对现在刚加入得影响
ll cnt=0;
while(!que.empty())
{
ll vi=que.top();
if(vi-T[i]-sum>0) break;
cnt+=vi-sum;//若今天会融化完全,则加上,今天的剩余量
que.pop();
}
sum+=T[i];
cnt+=(ll)que.size()*T[i];
if(i) printf(" ");
printf("%lld",cnt);
}
printf("\n");
return 0;
}
本题还有一个容易WA的地方就是数据的范围,唉,不知道吃了多少次亏了,还是没长记性,所有的数据除了一开始读的,后面计数的数据都要用ll,注意是所有的!!!一次全部改完(别问我为什么这样说)。