zoukankan      html  css  js  c++  java
  • poj3468区间加减查找——树状数组区间修改查询

    题目:http://poj.org/problem?id=3468

    增加一个更改量数组,施以差值用法则区间修改变为单位置修改;

    利用公式可通过树状数组维护两个数组:f与g而直接求出区间和。

    代码如下:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long n,q,a[100005]/*,b[100005],bg[100005]*/,l,r,ad;
    long long f[100005],g[100005],sum[100005];//f[x]为更改量 
    char dc;
    long long query(long long x)
    {
    	long long k=x;
    	long long summ=0;
    	for(;x;x-=x&-x)
    		summ+=f[x];
    	long long s2=0;
    	x=k;
    	for(;x;x-=x&-x)
    		s2+=g[x];
    	return (k+1)*summ-s2;
    }
    void add(long long x,long long y)//x单位置增加y
    {
    	long long k=x;
    	for(x;x<=n;x+=x&-x)
    		f[x]+=y,g[x]+=k*y;
    }
    int main()
    {
    	scanf("%lld%lld",&n,&q);
    	for(long long i=1;i<=n;i++)
    	{
    		scanf("%lld",&sum[i]);
    		sum[i]+=sum[i-1];
    //		b[i]=a[i]-a[i-1];
    //		for(int j=i-(i&-i)+1;j<=i;j++)f[i]+=b[j];//差值 
    //		bg[i]=i*b[i];
    //		for(int j=i-(i&-i)+1;j<=i;j++)g[i]+=bg[j];
    //		g[i]=i*f[i];
    	}
    	for(long long i=1;i<=q;i++)
    	{
    		scanf(" %c",&dc);
    		if(dc=='C')
    		{
    			scanf("%lld%lld%lld",&l,&r,&ad);
    			add(l,ad);add(r+1,-ad);
    		}
    		if(dc=='Q')
    		{
    			scanf("%lld%lld",&l,&r);
    			long long ans=query(r)+sum[r]-query(l-1)-sum[l-1];
    			printf("%lld
    ",ans);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    2019-12-18
    java读取XML文件,及封装XML字符串
    java不用中间变量交换两个值
    oracle获取当前月的第一个星期五
    2019-10-23
    HTTP中GET请求与POST请求的区别
    Java面试题整理(转载)
    java 字节流与字符流的区别
    20190822
    C++标准库string
  • 原文地址:https://www.cnblogs.com/Zinn/p/8440045.html
Copyright © 2011-2022 走看看