//可以用来求区间第K大。下一步,深入了解spaly
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int w[20010],vis[60010],pre[20010],cnt,n,m;
ll ans;int num;
struct p1{int a,b;}edge[60010];
struct pp{int x,p;char op;}command[500010];
struct node1
{
node1 *ch[2];
int r;//优先级
int v;//数值
int s;//节点数
node1(int v):v(v){ch[0]=ch[1]=NULL;r=rand();s=1;}
bool operator<(const node1 &pp1)const
{
return r<pp1.r;
}
int cmp(int x)const
{
if(x==v)return -1;
return x<v?0:1;
}
void maintain()
{
s=1;
if(ch[0]!=NULL)s+=ch[0]->s;
if(ch[1]!=NULL)s+=ch[1]->s;
}
};
node1 *root[200010];
void Rotate(node1* &o,int d)
{
node1 *k=o->ch[d^1];
o->ch[d^1]=k->ch[d];
k->ch[d]=o;
o->maintain();
k->maintain();
o=k;
}
void Insert(node1* &o,int x)
{
if(o==NULL){o=new node1(x);}
else
{
int d=(x < o->v?0:1);
Insert(o->ch[d],x);
if(o->ch[d] > o)
Rotate(o,d^1);
}
o->maintain();
}
void Delete(node1* &o,int x)
{
int d=o->cmp(x);
if(d==-1)
{
if(o->ch[0]!=NULL&&o->ch[1]!=NULL)
{
int d2=(o->ch[0]>o->ch[1]?1:0);
Rotate(o,d2);
Delete(o->ch[d2],x);
}
else if(o->ch[0]==NULL)
o=o->ch[1];
else if(o->ch[1]==NULL)
o=o->ch[0];
else
o=o->ch[0];
// delete u;
}
else
Delete(o->ch[d],x);
if(o!=NULL)
o->maintain();
}
int findd(int x)
{
if(x==pre[x])
return x;
return pre[x]=findd(pre[x]);
}
void Clear(node1* &o)
{
if(o->ch[0]!=NULL) Clear(o->ch[0]);
if(o->ch[1]!=NULL) Clear(o->ch[1]);
delete o;
o=NULL;
}
void Merge(node1* &o,node1* &o2)
{
if(o->ch[0]!=NULL)Merge(o->ch[0],o2);
if(o->ch[1]!=NULL)Merge(o->ch[1],o2);
Insert(o2,o->v);
delete o;
o=NULL;
}
void add(int x)
{
int u=findd(edge[x].a);
int v=findd(edge[x].b);
if(u!=v)
{
if(root[u]->s<root[v]->s)
{
pre[u]=v;
Merge(root[u],root[v]);
}
else
{
pre[v]=u;
Merge(root[v],root[u]);
}
}
}
void update(int x,int p)
{
int u=findd(x);
Delete(root[u],w[x]);
Insert(root[u],p);
w[x]=p;
}
int kth(node1* &o,int k)
{
if(o==NULL||o->s<k||k<=0)
return 0;
int s=(o->ch[1]==NULL?0:o->ch[1]->s);
if(k==s+1)
return o->v;
else if(k<=s)
return kth(o->ch[1],k);
else
return kth(o->ch[0],k-s-1);
}
void query(int x,int p)
{
num++;
ans+=kth(root[findd(x)],p);
}
int main()
{
int vv=0;
while(scanf("%d%d",&n,&m)!=EOF&&n)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
pre[i]=i;
ans=0,num=0,cnt=0;
for(int i=1;i<=n;i++)scanf("%d",&w[i]);
for(int i=1;i<=m;i++)scanf("%d%d",&edge[i].a,&edge[i].b);
while(1)
{
char str[5];scanf("%s",str);
int x,y=0,p=0;
if(str[0]=='E')break;
scanf("%d",&x);
if(str[0]=='D')vis[x]=1;
if(str[0]=='Q')scanf("%d",&p);
if(str[0]=='C')
{
scanf("%d",&y);
p=w[x];
w[x]=y;
}
command[cnt].op=str[0];
command[cnt].x=x;
command[cnt++].p=p;
}
for(int i=1;i<=n;i++)
{
if(root[i]!=NULL)
Clear(root[i]);
root[i]=new node1(w[i]);
}
for(int i=1;i<=m;i++)
{
if(!vis[i])
add(i);
}
for(int i=cnt-1;i>=0;i--)
{
if(command[i].op=='D')add(command[i].x);
else if(command[i].op=='C')update(command[i].x,command[i].p);
else query(command[i].x,command[i].p);
}
printf("Case %d: %.6lf\n",++vv,ans*1.0/num);
}
return 0;
}
数据结构之--Treap(hdu3726)
最新推荐文章于 2021-08-30 14:40:23 发布