zoukankan      html  css  js  c++  java
  • zkw模板

    水平有限,前缀和的前缀和什么的,rbq
    两个操作:

    1.区间l到r加上一个数x
    2.查询区间[l,r]的区间和

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,m,d,x,pt,ptl,ptr;//pt,ptl,ptr我也不知道应该叫什么,类似标记?
    long long tree[100000*4+2],pls[100000*4+2],ans;//pls为累加标记
    inline void add(int l,int r)
    {
    	l=l+d,r=r+d;
    	pt=0;
    	pls[l]+=x,tree[l]+=x;
    	if(l!=r)
    	{
    		pls[r]+=x,tree[r]+=(x<<pt);
    		while((l^1)!=r)
    		{
    			if(!(l&1))
    				pls[l^1]+=x,tree[l^1]+=(x<<pt);
    			if(r&1)
    				pls[r^1]+=x,tree[r^1]+=(x<<pt);
    			pt++;
    			l=l>>1,r=r>>1,tree[l]=tree[l<<1]+tree[l<<1|1]+(pls[l]<<pt),tree[r]=tree[r<<1]+tree[r<<1|1]+(pls[r]<<pt);
    		}
    	}
    	while(l>>=1)
    	{	
    		pt++;
    		tree[l]=tree[l<<1]+tree[l<<1|1]+(pls[l]<<pt);
    	}
    }
    long long getans(int l,int r)
    {
    	l=l+d,r=r+d;
    	ans=tree[l];
    	ptl=pt=1;
    	if(l!=r)
    	{
    		ans+=tree[r],ptr=1;
    		while((l^1)!=r)
    		{
    			if(!(l&1))
    				ans+=tree[l^1],ptl=ptl+pt;
    			if(r&1)
    				ans+=tree[r^1],ptr=ptr+pt;
    			pt=pt<<1;
    			l=l>>1;
    			r=r>>1;
    			ans=ans+pls[l]*ptl+pls[r]*ptr;
    		}
    		ptl+=ptr;
    	}
    	while(l>>=1)
    		ans+=pls[l]*ptl;
    	return ans;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	d=1;
    	while(d<n)
    		d<<=1;
    	d--;
    	for(int i=1;i<=n;i++)
    		scanf("%lld",&tree[d+i]);
    	for(int i=(n+d)>>1;i;i--)
    		tree[i]=tree[i<<1]+tree[i<<1|1];
    	int t,l,r;
    	while(m--)
    	{
    		scanf("%d%d%d",&t,&l,&r);
    		if(t==1)
    		{
    			scanf("%d",&x);
    			add(l,r);
    		}
    		else
    			printf("%lld
    ",getans(l,r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    软件工程个人作业01
    动手动脑
    大道至简感想终结篇
    课后作业
    反思
    课后作业
    不忘初心,方得始终
    课后作业
    沟通,让一切变得简单

  • 原文地址:https://www.cnblogs.com/syhien/p/7701269.html
Copyright © 2011-2022 走看看