[POI2015] LOG

题目链接
Splay树维护权值,数组模拟修改

点击查看代码
#include <bits/stdc++.h>
using namespace std;
int a[1000005];
int root,tot;
int read1()
{
	char cc=getchar();
	while(!(cc>=48&&cc<=57))
	{
		if(cc=='-')
		{
			break;
		}
		cc=getchar();
	}
	bool f=false;
	int s=0;
	if(cc=='-')
	{
		f=true;
	}
	else
	{
		s=cc-48;
	}
	while(1)
	{
		cc=getchar();
		if(cc>=48&&cc<=57)
		{
			s=s*10+cc-48;
		}
		else
		{
			break;
		}
	}
	if(f==true)
	{
		s=-s;
	}
	return s;
}
struct t1
{
	int fa,s[2],size,cnt;
	long long v,sum;
}t[1000005];
void New(int va)
{
	tot++;
	t[tot].size=t[tot].cnt=1;
	t[tot].v=t[tot].sum=va;
}
int get(int x)
{
	return x==t[t[x].fa].s[1];
}
void maintain(int x)
{
	t[x].size=t[t[x].s[0]].size+t[t[x].s[1]].size+t[x].cnt;
	if(x>2)
	{
		t[x].sum=t[t[x].s[0]].sum+t[t[x].s[1]].sum+t[x].v*t[x].cnt;
	}
}
void rotate(int x)
{
	int y=t[x].fa,z=t[y].fa,opt=get(x);
	t[y].s[opt]=t[x].s[opt^1];
	if(t[x].s[opt^1])
	{
    	t[t[x].s[opt^1]].fa=y;
    }
	t[x].s[opt^1]=y;
	t[y].fa=x;
	t[x].fa=z;
	if(z)
	{
		t[z].s[y==t[z].s[1]]=x;//此时y的父亲节点已经发生改变,因而不能应用get函数 
	}
	maintain(y);
	maintain(x);
}
void Splay(int x,int k)
{
	while(t[x].fa!=k)
	{
		int y=t[x].fa,z=t[y].fa;
		if(z!=k)
		{
			if(get(x)==get(y))
			{
				rotate(y);
			}
			else
			{
				rotate(x);
			}
		}
		rotate(x);
	}
	if(k==0)
	{
		root=x;
	}
}
void Insert(int va)
{
	int x=root,fa,opt;
	while(x!=0)
	{
		if(va<t[x].v)
		{
			fa=x;
			x=t[x].s[0];
			opt=0;
		}
		else if(va==t[x].v)
		{
			t[x].cnt++;
			maintain(x);
			break;
		}
		else
		{
			fa=x;
			x=t[x].s[1];
			opt=1;
		}
	}
	if(x==0)
	{
		New(va); 
		x=tot;
		t[fa].s[opt]=x;
		t[x].fa=fa;
	}
	Splay(x,0);
}
void Delete(int va)
{
	int x=root;
	while(x!=0)
	{
		if(va<t[x].v)
		{
			x=t[x].s[0];
		}
		else if(va==t[x].v)
		{
			t[x].cnt--;
			maintain(x);
			break;
		}
		else
		{
			x=t[x].s[1];
		}
	}
	Splay(x,0);
}
//不需要真的把它删除呀,把它的个数设为0就好了 
long long ask(long long va)
{
	Insert(va);
	long long ans=t[t[root].s[1]].sum-(t[t[root].s[1]].size-1)*va;
	Delete(va);
	return ans;
}
int main()
{
	int n,m;
	cin>>n>>m;
	New(INT_MIN),New(INT_MAX);
	t[0].size=t[0].sum=0;
	t[1].s[1]=2;
	t[1].size=2;
	root=1;
	t[2].fa=1;
	t[1].sum=t[2].sum=0;
	long long sum=0;
	for(int i=1;i<=m;i++)
	{
		char opt;
		long long u,v;
		cin>>opt;
		u=read1();
		v=read1();
		if(opt=='U')
		{
			if(a[u]!=0)
			{
				Delete(a[u]);
			}
			if(v!=0)
			{
				Insert(v);
			}
			sum-=a[u];
			a[u]=v;
			sum+=v;
		}
		else
		{
			long long tmp=sum-ask(v);
			if(tmp>=u*v)
			{
				puts("TAK");
			}
			else
			{
				puts("NIE");
			}
		}
	}
	return 0;
}
posted @ 2024-02-20 12:19  D06  阅读(5)  评论(0编辑  收藏  举报