zoukankan      html  css  js  c++  java
  • luogu P5494 【模板】线段树*

    操作过程在那里写的非常清楚了,这里主要粘一下代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    
    using namespace std;
    
    typedef long long LL;
    const int N=200009;
    int n,m,rt[N],bin[N*32],cnt,Index=1;
    struct Tree
    {
    	int l,r;
    	LL siz;
    	#define l(x) a[x].l
    	#define r(x) a[x].r
    	#define siz(x) a[x].siz
    }a[N*40];
    
    void recycle(int x)
    {
    	bin[++bin[0]]=x;
    	l(x)=r(x)=siz(x)=0;
    }
    
    int New() { return bin[0]>0?bin[bin[0]--]:++cnt; }
    
    void push_up(int k) { siz(k)=siz(l(k))+siz(r(k)); }
    
    void Modify(int &k,int l,int r,int x,LL y)
    {
    	if(!k) k=New();
    	if(l==r)
    	{
    		siz(k)+=y;
    		return;
    	}
    	int mid=l+r>>1;
    	if(mid>=x)
    		Modify(l(k),l,mid,x,y);
    	else
    		Modify(r(k),mid+1,r,x,y);
    	push_up(k);
    }
    
    void init()
    {
    	scanf("%d %d",&n,&m);
    	for (int i=1;i<=n;i++)
    	{
    		LL x;
    		scanf("%lld",&x);
    		Modify(rt[1],1,n,i,x);
    	}
    }
    
    LL Querysum(int k,int l,int r,int x,int y)
    {
    	if(!k) return 0;
    	if(l>=x&&r<=y)
    		return siz(k);
    	int mid=l+r>>1;
    	LL res=0;
    	if(mid>=x)
    		res+=Querysum(l(k),l,mid,x,y);
    	if(mid<y)
    		res+=Querysum(r(k),mid+1,r,x,y);
    	return res;
    }
    
    int QueryKth(int k,int l,int r,int x)
    {
    	if(l==r)
    		return l;
    	int mid=l+r>>1;
    	if(siz(l(k))>=x)
    		return QueryKth(l(k),l,mid,x);
    	return QueryKth(r(k),mid+1,r,x-siz(l(k)));
    }
    
    int merge(int x,int y)
    {
    	if(!x||!y) return x+y;
    	siz(x)+=siz(y);
    	l(x)=merge(l(x),l(y));
    	r(x)=merge(r(x),r(y));
    	recycle(y);
    	return x;
    }
    
    void split(int x,int &y,LL k)
    {
    	y=New();
    	if(siz(l(x))<k)
    		split(r(x),r(y),k-siz(l(x)));
    	else
    		swap(r(x),r(y));
    	if(siz(l(x))>k)
    		split(l(x),l(y),k);
    	siz(y)=siz(x)-k;
    	siz(x)=k;
    }
    
    void work()
    {
    	LL opt,x,y,z;
    	while(m--)
    	{
    		scanf("%lld",&opt);
    		if(opt==2)
    		{
    			scanf("%lld %lld %lld",&x,&y,&z);
    			Modify(rt[x],1,n,z,y);
    		}
    		else if(opt==3)
    		{
    			scanf("%lld %lld %lld",&x,&y,&z);
    			printf("%lld
    ",Querysum(rt[x],1,n,y,z));
    		}
    		else if(opt==4)
    		{
    			scanf("%lld %lld",&x,&y);
    			if(siz(rt[x])<y)
    				puts("-1");
    			else
    				printf("%d
    ",QueryKth(rt[x],1,n,y));
    		}
    		else if(opt==1)
    		{
    			scanf("%lld %lld",&x,&y);
    			rt[x]=merge(rt[x],rt[y]);
    		}
    		else
    		{
    			scanf("%lld %lld %lld",&x,&y,&z);
    			LL k1=Querysum(rt[x],1,n,1,y-1),k2=Querysum(rt[x],1,n,y,z);
    			int tmp;
    			split(rt[x],rt[++Index],k1);
    			split(rt[Index],tmp,k2);
    			rt[x]=merge(rt[x],tmp);
    		}
    	}
    }
    
    int main()
    {
    	init();
    	work();
    	return 0;
    }
    
    由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!
  • 相关阅读:
    Javascript 正确用法 二
    c# 未能载入文件或程序集
    Linux系统备份
    环保创业的可行之道——Leo鉴书上66
    Oracle的序列
    UVA 10574
    网页内容的html标签补全和过滤的两种方法
    使用POI来实现对Excel的读写操作
    OVER(PARTITION BY)函数介绍
    Kill 正在执行的存储过程
  • 原文地址:https://www.cnblogs.com/With-penguin/p/13090710.html
Copyright © 2011-2022 走看看