線段樹專題——長博客(草稿版本)。

板子

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define mset(var,val)	 memset(var,val,sizeof(var))
#define LL long long 
#define eps 0.000001
#define inf 0x7f7f7f7f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
#define lowbit(x)   x&(-x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=(x<<3)+(x<<1)+a-'0'; a=getchar();}return x*y;
}
#define N 1000009
using namespace std;
#ifdef WIN32
#define LL "%I64d\n"
#else 
#define LL "%lld\n"
#endif
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

區間加,區間詢問

(luogu線段樹模板1)

long long sum[N<<2|1],add[N<<2|1]={0};

inline void update(int rt){
	sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
inline void build(int l,int r,int rt)
{
	if ( l==r  )
	{
		sum[rt]=read();
		add[rt]=0;
		return ;
	}	
	int m=(l+r)>>1;
	build(lson);
	build(rson);
	update(rt);	
}
inline void color (int l,int r,int rt,int v)
{
	sum[rt]+=(r-l+1)*v;
	add[rt]+=v;
}
inline void push_col(int l,int r,int rt)
{
	if ( add[rt] )
	{
		int m=(l+r)>>1;
		color(lson,add[rt]);
		color(rson,add[rt]);
		add[rt]=0;
		return ; 
	}
}
inline void modify(int l,int r,int rt,int nowl,int nowr,int v)
{
	if ( nowl <= l && r <= nowr )
	{
		color(l,r,rt,v);
		return ;
	}
	int m=(l+r)>>1;
	push_col(l,r,rt);
	if ( nowl <= m )	
	modify(lson,nowl,nowr,v);
	if ( nowr >= m+1)
	modify(rson,nowl,nowr,v);
	update(rt);
}
inline long long query(int l,int r,int rt,int quel,int quer)
{
	if( quel<=l && r<=quer)
	{
		return sum[rt];
	}
	push_col(l,r,rt);
	long long ans=0;
	int m=(l+r)>>1;
	if ( quel <= m)
		ans+=query(lson,quel,quer);
	if ( quer>=m+1)
		ans+=query(rson,quel,quer);
	return ans;		
}  
int main()
{
	int n,m;
	n=read();	m=read();
	build(1,n,1);
	while ( m-- )
	{
		int cmd=read();
		if ( cmd==1 )
		{
			int x,y,k; 
			x=read();y=read();k=read();
			modify(1,n,1,x,y,k);			
		}
		else {
			int x,y;
			x=read();y=read();
			printf(LL,query(1,n,1,x,y));
		}
	} 
	return 0;
}

區間加,區間乘,區間模,區間詢問

(luogu線段樹模二)

long long sum[N<<2|1],add[N<<2|1],mul[N<<2|1];
long long P;

void update(int rt )
{
	sum[rt] = sum[rt<<1] + sum[rt<<1|1] ; sum[rt]%=P;
}
void color(int l,int r,int rt,int a,int b)
{
	sum[rt] = ( sum[rt]*a )%P + (long long)(r-l+1)*b; sum[rt]%=P;
	add[rt] = (add[rt]*a+b)%P;
	mul[rt] = (mul[rt]*a)%P;
}

void push_col(int l,int r,int rt)
{
	if ( mul[ rt ] != 1 || add[rt] != 0 )
	{
		int m = ( l+r )>>1; 
		color(lson , mul[rt] , add[rt]);
		color(rson , mul[rt] , add[rt]);
		add[rt] = 0; 
		mul[rt] = 1; 
	}
}
void build(int l,int r,int rt)
{
	add[rt] = 0 ;
	mul[rt] = 1; 
	if ( l == r )
	{
		scanf("%d",&sum[rt]);
		return ; 
	}
	int  m =( l+r ) >>1; 
	build( lson  ) ; 		build( rson );
	update(rt);
}

void modify(int l,int r,int rt,int nowl,int nowr,int a,int b){//*a+b
	if(nowl <= l && r <= nowr){
		color(l,r,rt,a,b);
		return;
	}
	push_col(l,r,rt);
	int m = (l+r)>>1;
	if(nowl <= m)modify(lson,nowl,nowr,a,b);
	if(m < nowr)modify(rson,nowl,nowr,a,b);
	update(rt);
}
long long query(int l,int r,int rt,int quel,int quer)
{
	if( quel <= l && r <= quer )	return sum[rt];
	push_col(l,r,rt);
	int m = ( l+r ) >>1; 
	long long ans = 0; 
	if ( quel <= m )	ans += query(lson , quel , quer )%P ;
	if ( m < quer )		ans += query(rson , quel , quer )%P ;
	return ans%P;
}

int main()
{
	int n , m;
	scanf("%d%d%lld",&n,&m,&P);
	build(  1 , n , 1 );
	while ( m-- )
	{
		int cmd; 
		scanf("%d",&cmd);
		if( cmd != 3 )
		{
			int x, y , k; 
			scanf("%d%d%d",&x,&y,&k);
			if ( cmd == 1 )	modify( 1, n, 1, x, y , k , 0 );
			else 			modify( 1, n, 1, x, y , 1 , k );
			
		}
		else {
			int l ,r ; 
			scanf("%d%d",&l,&r);
			printf("%d\n",query(1,n,1,l,r));
		}
	}
}

區間和,單點修改1

codevs 線段樹練習(1080)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct rode
{	
	int l;	
	int r;	
	int sum;
}; 
struct rode t[400001];
int n,m;
int a[100001];	
void build(int left,int right,int k)
{
	int mid =( left + right ) / 2;
	if ( left == right )	
	{
		t[k].l = left, t[k].r = right, t[k].sum = 0 ;
		return ;
	}	
	t[k].l = left; t[k].r = right; t[k].sum = 0;	
	build(left,mid,k*2);   build(mid+1,right,k*2+1);
}	
void insert(int n,int d,int k)
{
	int mid = ( t[k].l + t[k].r ) / 2 ;	
	if ( t[k].l == t[k].r && d == t[k].r)
	{
		t[k].sum += n; return ;
	} 	
	if(d<=mid)		insert(n,d,k*2);	
	else if ( d > mid)			insert(n,d,k*2+1);	
	t[k].sum	=	t[k*2].sum	+	t[k*2+1].sum;	
}
int search(int l,int r,int k)
{
	int mid;	
	if(t[k].l==l&&t[k].r==r)		return t[k].sum;	
	mid=(t[k].l+t[k].r)/2;	
	if(r<=mid)		return search(l,r,k*2);
	else if(l>mid)	return search(l,r,k*2+1);	
	else 	return search(l,mid,k*2)+search(mid+1,r,k*2+1);
}
int main()
{
	scanf("%d",&n);
	build(1,n,1);
	for (int i = 1; i <= n; i++)
		scanf("%d",&a[i]),
		insert(a[i],i,1);	
		
	scanf("%d",&m);
	for (int i = 1; i <= m; i++)
	{
		int f,x,y;
		scanf("%d%d%d",&f,&x,&y);		
		if ( f == 1 )	insert(y,x,1);			
		if ( f == 2 )	printf("%d\n",search(x,y,1));
	}	
	return 0;
}

區間和,單點修改

codevs 線段樹練習(1081)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<deque>
using namespace std; 
const int maxn = 100000;
int a[10000]={0};
struct node {
	int l,r,d; 
}tree[maxn*4+5];
int ans = 0; 

void make_tree(int l,int r,int k){
	tree[k].l = l; tree[k].r = r; tree[k].d = 0; 
	if ( l == r )	return ; 
	int mid = (l+r)>>1; 
	make_tree(l,mid,k<<1); 		make_tree(mid+1,r,k*2+1); 
}

void make(int l,int r,int d,int k){
	if ( r<tree[k].l || tree[k].r < l)			return ; 
	if ( l <= tree[k].l && tree[k].r <= r  ){
		tree[k].d += d; 						return ;  
	}
	make(l,r,d,k*2); 		make(l,r,d,k*2+1);
}

void ask(int k,int count){
	if ( count<tree[k].l || count>tree[k].r )	return ; 
	ans += tree[k].d; 
	ask(k*2,count); 		ask(k*2+1,count);
}
int main(){
	int n , m; 

	cin>>n; 
	for ( int i = 1 ; i <= n; i++)
		scanf("%d",&a[i]);
	make_tree(1,n,1);	
		
	cin>>m; 
	for ( int i = 1; i <= m; i++)
	{
		ans = 0; 
		int l,r,v,f;
		cin>>f; 
		if ( f == 1 ){
			scanf("%d%d%d",&l,&r,&v);
			make(l,r,v,1);
		}
		else {
			scanf("%d",&v);
			ask(1,v);
			printf("%d\n",ans+a[v]);
		}
	}	
	return 0; 
}

區間和,單點修改

codevs 線段樹練習(1082)

#include<bits/stdc++.h>
using namespace std;
const int maxn=200011*4+9;
const int maxm=200100;
//long long sum[maxn],ad[maxn];
#define LL long long 
struct Po{
	LL sum,ad,l,r;
}tree[maxn];
long long nu[maxm];
long long n;

void push_up(LL k){
	tree[k].sum = tree[k<<1].sum + tree[k<<1|1].sum;
}

void build(long long l,long long r,long long k)
{
	tree[k].l = l; tree[k].r = r; tree[k].sum=0; tree[k].ad = 0;
	
	if(l==r)
	{
		tree[k].sum = nu[l];
		return;
	}
	
	int mid=(l+r)/2;
	build(l,mid,k*2);
	build(mid+1,r,k*2+1);
	push_up(k);
}

void push_down(LL k,LL x,LL y){
	if ( tree[k].ad){
		tree[k<<1].ad    += tree[k].ad; 
		tree[k<<1|1].ad  += tree[k].ad; 
		tree[k<<1].sum   += tree[k].ad*x; 
		tree[k<<1|1].sum += tree[k].ad*y; 
		tree[k].ad = 0; 
	}
}
void add(LL st,LL ed,LL v,long long k)
{
	if ( ed < tree[k].l || st > tree[k].r   )		return ; 	
	long long mid=(tree[k].l+tree[k].r)/2;
	if(tree[k].l>=st&&ed>=tree[k].r)
	{
		tree[k].sum += v*(tree[k].r-tree[k].l+1);
		tree[k].ad  += v;
		return;
	}	
	
	push_down(k,mid-tree[k].l+1,tree[k].r-mid);
	if(st<=mid)		add(st,ed,v,2*k);
	if(ed>mid)		add(st,ed,v,2*k+1);	
	push_up(k);
}


LL fin(LL st,LL ed,LL k){
	
	if ( st > tree[k].r || ed < tree[k].l )			return 0; 
	if ( st <= tree[k].l&& tree[k].r<= ed )			return tree[k].sum; 
	
	LL mid = (tree[k].r+tree[k].l)>>1;	
	push_down(k,mid-tree[k].l+1,tree[k].r-mid);
	
	LL ans = 0; 
	if ( st <= mid )			ans += fin(st,ed,k<<1);	
	if ( ed > mid )				ans += fin(st,ed,k<<1|1);
	return ans; 
}
int main()
{

	scanf("%lld",&n);
	for(int i=1;i<=n;i++)	scanf("%lld",&nu[i]);
	build(1,n,1);
	long long m,flag,l,r,v;
	scanf("%lld",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%lld",&flag);
		if(flag==1)
		{
			scanf("%lld %lld %lld",&l,&r,&v);
			add(l,r,v,1);
		}
		if(flag==2)
		{
			scanf("%lld %lld",&l,&r);
			printf("%lld\n",fin(l,r,1));
		}
	}
}

區間加,詢問區間內能被7整除的數字

codevs 線段樹練習(4919)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL inf=0x3f3f3f3f3f3f3f3fLL;
const int maxn=1e5+10;
int n,q,c[maxn],a,b,x,temp[7];
string str;
struct Node{
int l,r,add,mod[7];
} tree[maxn<<2];
void pushup(int pos)
{
	for(int i=0;i<7;i++) 
		tree[pos].mod[i]=tree[ pos<<1 ].mod[i]+tree[ pos<<1|1 ].mod[i];
}
//void build(int pos,int l,int r)
//{
//	tree[pos].l = l,tree[pos].r = r,tree[pos].add = 0;
//	for(int i = 0 ; i < 7 ;i++) 		tree[pos].mod[i]=0;
//	if( l == r )
//	{
//		tree[pos].mod[ c[l]%7 ]=1;
//		return ;
//	}
//	int mid=( tree[pos].l+tree[pos].r ) >> 1;
//	build(pos<<1,l,mid);
//	build(pos<<1|1,mid+1,r);
//	for(int i=0;i<7;i++) tree[pos].mod[i]=tree[pos<<1].mod[i]+tree[pos<<1|1].mod[i];
//}
void build(int pos,int l,int r){
	tree[pos].l = l; tree[pos].r = r; tree[pos].add = 0;
	if ( tree[pos].l == tree[pos].r ){
		tree[pos].mod[ c[l]%7 ] = 1; 
		return ; 
	} 
	int mid = ( l + r ) >> 1; 
	build(pos<<1,l,mid);			build(pos<<1|1,mid+1,r);
	pushup(pos);
}
void change(int pos,int x){
	for ( int i = 0; i <= 6; i++)	temp[ (i+x)%7 ] = tree[pos].mod[i];
	for ( int i = 0; i <= 6; i++)	tree[pos].mod[i] = temp[i];
}
void pushdown(int pos){
	if ( tree[pos].l == tree[pos].r )		return ; 
	if ( tree[pos].add == 0 )				return ; 
	tree[pos<<1].add   += tree[pos].add; 
	tree[pos<<1|1].add += tree[pos].add; 
	change(pos<<1,tree[pos].add);	change(pos<<1|1,tree[pos].add);
	tree[pos].add = 0; 
}
void update(int pos,int st,int ed,int x){
	if ( ed < tree[pos].l || st > tree[pos].r )		return ; 
	if ( st <= tree[pos].l && tree[pos].r <= ed){
		tree[pos].add += x; 	change(pos,x);		return ; 
	} 
	pushdown(pos);
	int mid = (tree[pos].l+tree[pos].r)>>1; 
	if ( st <= mid )		update(pos<<1,st,ed,x);
	if ( ed >  mid )		update(pos<<1|1,st,ed,x);
	pushup(pos);	
}
int query(int pos,int l,int r)
{
	pushdown(pos);
	if(tree[pos].l>=l&&tree[pos].r<=r) 		return tree[pos].mod[0];
	int mid=(tree[pos].l+tree[pos].r)>>1;
	
	int ans = 0;
	if(l<=mid) 								ans += query(pos<<1,l,r);
	if(r> mid) 								ans += query(pos<<1|1,l,r);
	return ans; 
}
int main(){
	

	std::ios::sync_with_stdio(false);

	cin>>n; 
	for ( int i = 1; i <= n; i++)	cin>>c[i];
	build(1,1,n);
	cin>>q; 
	while ( q-- ){
		cin>>str; 
		if ( str[0] == 'a'){
			cin>>a>>b>>x; 
			update(1,a,b,x);
		}
		if ( str[0] == 'c'){
			cin>>a>>b; 
			cout<<query(1,a,b)<<endl; 
		}
	}
	
	return 0; 
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章