【模板】zkw线段树の基本操作

整理了一下zkw线段树的基本操作:

1.修改元素值:给定x,y,修改a[x]的值为y;

2.查询元素值:给定x,输出a[x]的值;

3.区间增减:给定l,r,x,将从a[l]到a[r](含al和ar),即区间[l,r]中的每个值都加上x;

4.区间求和:给定l,r,输出从a[l]到a[r](含al和ar),即区间[l,r]中的每个元素之和。

#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<cstring>
#define LL long long

LL x,a,b,c,n,m,pre=1;
LL num[10000000],numm[10000000];

inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();

    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

inline void add(int a,int b)
{
	num[a+=pre]+=b;
	numm[a]=(a-pre)*num[a];
	a>>=1;
	while(a)
	{
		num[a]=num[a<<1]+num[(a<<1)+1];
		numm[a]=numm[a<<1]+numm[(a<<1)+1];
		a>>=1;
	}
}

inline LL query(int a,int b)
{
	LL ans=0;
	a+=pre-1;
	b+=pre+1;
	while(a^b^1)
	{
		if(~a&1)
			ans+=num[a^1];
		if(b&1)
			ans+=num[b^1];
		a>>=1;
		b>>=1;
	}
	return ans;
}

inline LL nquery(int a,int b)
{
	LL ans=0;
	a+=pre-1;
	b+=pre+1;
	while(a^b^1)
	{
		if(~a&1)
			ans+=numm[a^1];
		if(b&1)
			ans+=numm[b^1];
		a>>=1;
		b>>=1;
	}
	return ans;
}

int main()
{
	int i;
	n=read();
	m=read();
	n=read();
	while(pre<=n)
		pre<<=1;
	for(i=pre+1;i<=pre+n;++i)
		num[i]=read();
	for(i=pre+n;i>pre;--i)
	{
		num[i]-=num[i-1];
		numm[i]=(i-pre)*num[i];
	}
	for(i=pre-1;i>=1;--i)
	{
		num[i]=num[i<<1]+num[(i<<1)+1];
		numm[i]=numm[i<<1]+numm[(i<<1)+1];
	}
	for(i=1;i<=m;++i)
	{
		x=read();
		if(x==1)
		{
			a=read(),b=read();
			add(a,b),add(a+1,-b);
			printf("-1\n");
		}
		if(x==2)
	 	{
	 		a=read();
			printf("%lld\n",query(1,a));
		}
		if(x==3)
		{
			a=read(),b=read(),c=read();
			add(a,c),add(b+1,-c);
			printf("-1\n");
		}
		if(x==4)
		{
			a=read(),b=read();
			printf("%lld\n",(query(1,b)*(b+1)-nquery(1,b))-query(1,a-1)*a+nquery(1,a-1));
		}
	}
	printf("\n");
	return 0;
}

于是作死的做了CODEVS 1954 线段树。

已被saffah前辈虐哭0.0

求大神帮助………………

时间: 2024-10-10 05:11:13

【模板】zkw线段树の基本操作的相关文章

[模板]树状数组1/ZKW线段树

https://www.luogu.org/problemnew/show/P3374 1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 #define rson (o<<1|1) 5 #define lson (o<<1) 6 const int N = 530000<<1;//zkw线段树只能查询(0,bit),所以只有bit-2个叶节点,bit-2<n

回档|忠诚2|zkw线段树

线段树,大家一看就明白了吧,这题就是一模板题,我学zkw线段树用的.单点维护,区间最值. 题目是tyvj的忠诚2. #include"iostream" #include"cstdio" using namespace std; int M; int T[10000000]; int read() { char c=getchar(); int a=0; while (c<'0'||c>'9') c=getchar(); while (c>='0'

ZKW线段树 非递归版本的线段树

学习和参考 下面是支持区间修改和区间查询的zkw线段树模板,先记下来. #include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <iomanip> #include <cstdlib> #include <cstdio> #include <string> #include <vect

解析&#183;优化 ZKW线段树

德鲁伊!大自然已经听命于我了! 死亡之翼长子奈法利安 ZKW天下第一! 摘自某群聊天记录 ZKW线段树,即非递归形式的线段树,出自终极大犇ZKW的论文<统计的力量>.与普通的线段树相比,ZKW线段树由于是非递归形式,效率极高,代码也极短,成为了OI比赛中极为实用的优化算法之一.虽然ZKW线段树无法处理有运算优先级的线段树问题,但是在一般的问题上和常数偏大的问题上总能带来极强的游戏体验. ZKW线段树的建树 普通线段树 1 / 2 3 <---------------"弱小,可伶

【bzoj3685】普通van Emde Boas树 权值zkw线段树

原文地址:http://www.cnblogs.com/GXZlegend/p/6809743.html 题目描述 设计数据结构支持:1 x  若x不存在,插入x2 x  若x存在,删除x3    输出当前最小值,若不存在输出-14    输出当前最大值,若不存在输出-15 x  输出x的前驱,若不存在输出-16 x  输出x的后继,若不存在输出-17 x  若x存在,输出1,否则输出-1 输入 第一行给出n,m 表示出现数的范围和操作个数接下来m行给出操作n<=10^6,m<=2*10^6,

普及向 ZKW线段树!

啊,是否疲倦了现在的线段树 太弱,还递归! 那我们就欢乐的学习另外一种神奇的线段树吧!(雾 他叫做zkw线段树 这个数据结构灰常好写(虽然线段树本身也特别好写……) 速度快(貌似只在单点更新方面比线段树快……) 是一种自底向上非递归版本的线段树! 首先我们来看一个ppt,<统计的力量>这个是发明人的PPT(啊,ppt内的代码是错的…… 統計的力量 好吧,我们来写吧~ 首先预备条件: int M,T[maxn*2+2]; M指的是什么呢?M就指的是这颗zkw线段树最下面的那个点之前的编号是什么

【原创】洛谷 LUOGU P3373 【模板】线段树2

P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字的个数.操作的总个数和模数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k 操作2: 格式:2 x

洛谷P3373 【模板】线段树 2

 P3373 [模板]线段树 2 47通过 186提交 题目提供者HansBug 标签 难度提高+/省选- 提交  讨论  题解 最新讨论 为啥WA(TAT) 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字的个数.操作的总个数和模数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4

洛谷P3372 【模板】线段树 1

P3372 [模板]线段树 1 153通过 525提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 [模板]线段树1(AAAAAAAAA- [模板]线段树1 洛谷评测机出问题了吗? 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接