[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;
}