您的位置:首页 > 其它

Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)C. Producing Snow

2018-03-13 13:36 706 查看
题意:有一个人,第i天会堆大小为v[i]的雪堆,但由于天气因素,第i天的气温为t[i],相应的所有雪堆会融化t[i]的雪,如果雪堆大小小于t[i],那就融化完了。
思路:前缀和+二分+差分,前缀和+优先队列。
前缀和+二分+差分:对于第i堆雪,假设它在第j天会融化完毕,那么它对第i到j-1天的贡献都是1(这里对次数进行差分,对第j天特殊处理一下就好),区间加即可。
前缀和+优先队列:这就简单了,每次加入新雪堆,然后将队列中不合要求的踢掉就好了。
注意:会发现两种思路代码实现都有+sum[i-1]的操作,很巧很简单的,可能会想不到哈。。。

ac代码1:#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

typedef long long ll;
const int N=1e5+5;

ll v
,t
,sum
={0},ans
={0};
int cnt
,p
={0};
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%I64d",&v[i]);
for(int i=1;i<=n;i++) scanf("%I64d",&t[i]);
for(int i=1;i<=n;i++) sum[i]=t[i]+sum[i-1];
for(int i=1;i<=n;i++){
int k=upper_bound(sum+i,sum+n+1,v[i]+sum[i-1])-sum;
if(sum[k]==v[i]) cnt[i]=k;
else{
ans[k]+=v[i]+sum[i-1]-sum[k-1];
cnt[i]=k-1;
}
}
for(int i=1;i<=n;i++){
if(cnt[i]>=i){
p[i]++,p[cnt[i]+1]--;
}
}
for(int i=1;i<=n;i++){
p[i]+=p[i-1];
ans[i]+=p[i]*t[i];
}
for(int i=1;i<=n;i++)
printf("%I64d%c",ans[i],i==n?'\n':' ');
return 0;
}ac代码2:#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;

typedef long long ll;
const int N=1e5+5;

ll v
,t
,sum
={0},ans
={0};
int cnt
,p
={0};
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%I64d",&v[i]);
for(int i=1;i<=n;i++) scanf("%I64d",&t[i]);
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+t[i];
priority_queue<ll,vector<ll>,greater<ll> >q;
for(int i=1;i<=n;i++){
q.push(v[i]+sum[i-
4000
1]);
ll ans=0;
while(!q.empty()&&q.top()<=sum[i]){
ans+=q.top()-sum[i-1];
q.pop();
}
ans+=q.size()*t[i];
printf("%I64d%c",ans,i==n?'\n':' ');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐