• 「模板」 主席树/可持久化线段树/函数式线段树


    「模板」 主席树/可持久化线段树/函数式线段树

    <题目链接>


    我的理解就是建一堆不同的根,然后指向相同的点,或说是一堆不同的树共用着一部分点。

    挺费空间的,但是思路很巧妙啊,而且可持久化是很重要的东西。

    代码更新于 2018.06.27。

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    const int MAXN=200010;
    int n, m, q;
    class PersistableSegmentTree
    {
    	private:
    		int value[MAXN];
    		struct Node
    		{
    			int v;
    			Node *c[2];
    			Node(int v):v(v)
    			{
    				c[0]=c[1]=nullptr;
    			}
    			Node(int l, int r)
    			{
    				c[0]=c[1]=nullptr;
    				if(l==r)
    					return;
    				int mid=l+r>>1;
    				c[0]=new Node(l, mid);
    				c[1]=new Node(mid+1, r);
    			}
    			~Node(void)
    			{
    				if(c[0]!=nullptr)
    					delete c[0];
    				if(c[1]!=nullptr)
    					delete c[1];
    			}
    		}*root[MAXN];
    		void Update(Node* &i, Node* j, int l, int r, int v)
    		{
    			i=new Node(j->v+1);
    			if(l==r)
    			{
    				i->v=j->v+1;
    				return;
    			}
    			int mid=l+r>>1;
    			memcpy(i->c, j->c, sizeof j->c);
    			if(v>mid)
    				Update(i->c[1], j->c[1], mid+1, r, v);
    			else
    				Update(i->c[0], j->c[0], l, mid, v);
    		}
    		int Find(Node* i, Node* j, int l, int r, int k)
    		{
    			if(l==r)
    				return value[l];
    			int mid=l+r>>1, v=j->c[0]->v-i->c[0]->v;
    			if(k>v)
    				return Find(i->c[1], j->c[1], mid+1, r, k-v);
    			else
    				return Find(i->c[0], j->c[0], l, mid, k);
    		}
    	public:
    		PersistableSegmentTree(int n)
    		{
    			int *a=new int[n+1];
    			std::fill(root, root+n+1, nullptr);
    			for(int i=1; i<=n; ++i)
    			{
    				scanf("%d", &a[i]);
    				value[i]=a[i];
    			}
    			std::sort(value+1, value+n+1);
    			m=std::unique(value+1, value+n+1)-value-1;
    			root[0]=new Node(1, m);
    			for(int i=1, pos; i<=n; ++i)
    			{
    				pos=std::lower_bound(value+1, value+m+1, a[i])-value;
    				Update(root[i], root[i-1], 1, m, pos);
    			}
    			delete []a;
    		}
    		void Find(int l, int r, int k)
    		{
    			printf("%d
    ", Find(root[l-1], root[r], 1, m, k));
    		}
    }*T;
    int main(int argc, char** argv)
    {
    	scanf("%d %d", &n, &q);
    	T=new PersistableSegmentTree(n);
    	for(int i=1, l, r, k; i<=n; ++i)
    	{
    		scanf("%d %d %d", &l, &r, &k);
    		T->Find(l, r, k);
    	}
    	delete T;
    	return 0;
    }
    

    谢谢阅读。

  • 相关阅读:
    Nginx+Keepalived(双机热备)搭建高可用负载均衡环境(HA)
    库管理系统-- 后台管理开源啦,源码大放送
    .NET Core R2
    Linux gdb调试
    webpack React+ES6
    绿卡排队
    ABP分层设计
    vscode编写插件
    控制台程序的参数解析类库 CommandLine
    Net Core MVC6 RC2 启动过程分析
  • 原文地址:https://www.cnblogs.com/Capella/p/8575724.html
Copyright © 2020-2023  润新知