poj

时间:2019-08-01
本文章向大家介绍poj,主要包括poj使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

#include<iostream>
#include<string.h>
#include<cmath>
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<iomanip>
#define inf 0x3f3f3f3f
#define ios() std::ios::sync_with_stdio(false)
#define cin() cin.tie(0)
#define cout() cout.tie(0)
#define mem1(a) memset(a,0,sizeof(a))
#define mem2(b) memset(b,'\0',sizeof(b))
typedef long long ll;
using namespace std;

//10 5
//1 2 3 4 5 6 7 8 9 10 //十个数
//Q 4 4 ->4//查询操作:查询区间[4,4]内所有和
//Q 1 10 ->55
//Q 2 4 ->9
//C 3 6 3 //插入操作:对[3,6]中每一个数+3
//Q 2 4 ->15


// [1,10]
// / \
// [1,5] [6,10]
// / \ / \
// [1,3] [4,5] [6,8] [9,10]
// / \ / \ / \ / \
// [1,2] 3 4 5 [6,7] 8 9 10
// / \ / \
// 1 2 6 7
ll sum[400020],lazy[400020];

void build(int left,int right,int point)
//传入左区间、右区间、根节点
{
if(left==right)
{
cin>>sum[point];
return;
}
int mid=(left+right)/2;//>>1
build(left,mid,point<<1);//point<<1//先建立左节点
build(mid+1,right,point<<1|1);//建立右节点,节点数+1
//|位运算,先把a,b转化成二进制,然后位相或,有1出1,无1出0,比直接+1运算快
sum[point]=sum[point<<1]+sum[point<<1|1];//左右节点相加
}

void pushdown(int point,int len)
{
if(lazy[point])//表示有过懒惰标记,进行下面的push将其他下面的节点进行更新
{
lazy[point<<1]+=lazy[point];
lazy[point<<1|1]+=lazy[point];
sum[point<<1]+=lazy[point]*(len-(len>>1));
sum[point<<1|1]+=lazy[point]*(len>>1);
lazy[point]=0;//用完后取消标记
}
}

//left,r,1,n,1,up)
void update(int x,int y,int left,int right,int point,int up)
{
if(x<=left&&y>=right)
{
sum[point]+=up*(right-left+1);
lazy[point]+=up;//lazy标记改变量
return;
}
pushdown(point,right-left+1);
int mid=(left+right)/2;
if(x<=mid)
update(x,y,left,mid,point<<1,up);
if(y>mid)
update(x,y,mid+1,right,point<<1|1,up);
sum[point]=sum[point<<1]+sum[point<<1|1];
}

//left,r,1,n,1
ll query(int x,int y,int left,int r,int point)
{
//x,y是题目给定需要求的区间
//left和r是题目原有区间
if(x<=left&&y>=r)//和区间没有交集
return sum[point];
pushdown(point,r-left+1);
int mid=(left+r)/2;
ll sum=0;
if(x<=mid)
sum=query(x,y,1,mid,point<<1);
if(y>mid)
sum+=query(x,y,mid+1,r,point<<1|1);
return sum;
}
int main()
{
ios();
cin();
cout();
int n,m;
while(cin>>n>>m)
{
mem1(sum);
mem2(lazy);
build(1,n,1);//开始建树
//传入左区间、右区间、根节点
while(m--)
{
string ss;
int left,r,up;
cin>>ss;
if(ss[0]=='Q')
{
cin>>left>>r;
cout<<query(left,r,1,n,1)<<endl;;
}

else if(ss[0]=='C')
{
cin>>left>>r>>up;//up是插入的数字量
update(left,r,1,n,1,up);
}
}
}
return 0;
}

原文地址:https://www.cnblogs.com/OFSHK/p/11285667.html