zoukankan      html  css  js  c++  java
  • 雪(二分)(树状数组)


    我们可以先算出来雪堆在哪一天融化完。因为每天都有融化的量,在该天前的雪堆如果没有融化完成的话还会融化,所以记录融化量的前缀和,序列就有了单调性。

    有了单调递增的性质后,就可以用二分查找来降低这个复杂度了。(当然懒得打二分可以用lower_bound)

    之后算出来在哪一天融化之后,就把该天到那一天的范围内都加上1(可以用树状数组,也可以用线段树)

    注意如果不是在那一天刚好融化完要记录余数的。

    还有数据范围很大,记得开long long(好吧,我是直接define int long long了)

    下面是代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define MAXN 100010
    #define int long long
    using namespace std;
    int n;
    int t[MAXN],sum[MAXN],tag[MAXN],qian[MAXN],v[MAXN],yu[MAXN];
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    inline void push_up(int x){sum[x]=sum[ls(x)]+sum[rs(x)];}
    inline void solve(int x,int l,int r,int k)
    {
    	tag[x]+=k;
    	sum[x]+=k*(r-l+1);
    }
    inline void push_down(int x,int l,int r)
    {
    	int mid=(l+r)>>1;
    	solve(ls(x),l,mid,tag[x]);
    	solve(rs(x),mid+1,r,tag[x]);
    	tag[x]=0;
    }
    inline void build(int x,int l,int r)
    {
    	if(l==r)
    	{
    		sum[x]=v[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(ls(x),l,mid);
    	build(rs(x),mid+1,r);
    	push_up(x);
    }
    inline void update(int x,int l,int r,int ll,int rr,int k)
    {
    	if(ll>rr) return;
    	if(ll<=l&&r<=rr)
    	{
    		sum[x]+=(r-l+1)*k;
    		tag[x]+=k;
    		return;
    	}
    	int mid=(l+r)>>1;
    	push_down(x,l,r);
    	if(ll<=mid) update(ls(x),l,mid,ll,rr,k);
    	if(mid<rr) update(rs(x),mid+1,r,ll,rr,k);
    	push_up(x);
    }
    inline int query(int x,int l,int r,int ll,int rr)
    {
    	if(ll<=l&&r<=rr) return sum[x];
    	int mid=(l+r)>>1;
    	push_down(x,l,r);
    	long long ans=0;
    	if(ll<=mid) ans+=query(ls(x),l,mid,ll,rr);
    	if(mid<rr) ans+=query(rs(x),mid+1,r,ll,rr);
    	return ans;
    }
    signed main()
    {
    	freopen("snow.in","r",stdin);
    	freopen("snow.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%lld",&v[i]);
    	for(int i=1;i<=n;i++) scanf("%lld",&t[i]),qian[i]=qian[i-1]+t[i];
    	for(int i=1;i<=n;i++)
    	{
    		v[i]+=qian[i-1];
    		int cur=lower_bound(qian+i,qian+1+n,v[i])-qian;
    		if(qian[cur]==v[i])
    			update(1,1,n,i,cur,1);
    		else 
    		{
    			update(1,1,n,i,cur-1,1);
    			yu[cur]+=v[i]-qian[cur-1];
    		}
    	}
    	for(int i=1;i<=n;i++)
    	{
    		int ans=t[i]*query(1,1,n,i,i);
    		ans+=yu[i];
    		printf("%lld ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Eclipse建立Java工程中的三个JRE选项的区别(Use an execution environment JRE,Use a project specific JRE,Use default JRE)
    Maven项目报错:Missing artifact****和ArtifactDescriptorException: Failed to read artifact descriptor for***和Cannot change version of project facet Dynamic web module to 2.5
    使用jdk的keytool 生成CA证书的方法
    Linux shell逐行读取文件的方法
    ArrayList的实现原理
    时间复杂度总结
    RPC的原理总结
    hashcode和equals方法的区别和联系
    消息队列的应用场景总结
    Java中IO流中的装饰设计模式(BufferReader的原理)
  • 原文地址:https://www.cnblogs.com/fengxunling/p/9781576.html
Copyright © 2011-2022 走看看