Cod sursa(job #1674448)

Utilizator mikeshadowIon Complot mikeshadow Data 4 aprilie 2016 17:39:29
Problema Arbori de intervale Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <bits/stdc++.h>

using namespace std;

struct node;
typedef node* ln;

struct node
{
	int pr;

	int v;
	int dp;

	int id,sz;
	
	ln l, r;

	node (int v=0) : pr(rand()),v(v),l(0),r(0) { upd(); }

	void upd()
	{
		dp = v;
		if (l) dp=max(dp,l->dp);		
		if (r) dp=max(dp,r->dp);
			
		sz = 1;
		if (l) sz+=l->sz;
		id = sz;		
		if (r) sz+=r->sz;		
	}
};

ln root;

void split ( ln t, int x, ln &l, ln &r)
{
	l=r=0;
	if (!t) return;
	if (t->id <= x)
	{
		split(t->r, x - t->id, t->r, r);
		l = t;
	} else
	{
		split(t->l, x, l, t->l);
		r = t;
	}

	t->upd();
}

ln merge(ln l, ln r)
{
	if (!l || !r) return (l?l:r);

	if (l->pr > r->pr)
	{
		l->r = merge(l->r, r);
		l->upd();
		return l;
	} else
	{
		r->l = merge(l,r->l);
		r->upd();
		return r;
	}
}

void insert(int x, int p)
{
	ln l,r;
	split(root,p,l,r);
	root = merge(merge(l,new node(x)),r);
}

void erase(int p)
{
	ln l,r,t;
	split(root,p,l,r);
	split(r,1,r,t);
	root = merge(l,t);
}

void show(ln t)
{
	if (!t) return;
	show(t->l);
	cout<<' '<<t->v;
	show(t->r);
}

int query(int x, int y)
{
	ln l,t,r;
	split(root, x, l, t);
	split(t, y-x+1, t, r);
	
	int m = t->dp;
	
	root = merge(merge(l,t),r);
	return m;
}

int main()
{
	ifstream cin("arbint.in");
	ofstream cout("arbint.out");
	
	srand(time(0));
	
	root = 0;
	
	int n,m;
	cin>>n>>m;
	for (int i=0; i<n; i++)
	{
		int x;
		cin>>x;
		insert(x,i);
	}
	
	while (m--)
	{
		int t,x,y;
		cin>>t>>x>>y;
		if (!t) cout<<query(x-1,y-1)<<'\n';
		else erase(x-1),insert(y,x-1);	
	}

    return 0;
}