#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#define L ch[rt][0]
#define R ch[rt][1]
const int N = 411111;
const int maxn = 111111;
int ch[maxn][2], aux[maxn], num[maxn], size[maxn], cnt[maxn];
int Node[511111];
int weight[N];
int val[maxn],tot,tot1;
bool v[maxn];
inline void NewNode(int &rt)
{
if(tot1)
rt=Node[--tot1];
else
rt=++tot;
}
struct Treap
{
int rt;
inline void init()
{
rt=0;
size[rt] = 0;
ch[rt][0] = ch[rt][1] = 0;
aux[rt] = 0;
v[rt]=false;
}
inline void pushup(int rt)
{
size[rt] = cnt[rt] + size[L]+size[R];
}
inline void rotate(int &rt,int f)
{
int t=ch[rt][!f];
ch[rt][!f]=ch[t][f];
ch[t][f]=rt;
pushup(rt),pushup(t);
rt=t;
}
void insert(int &rt,int key)
{
if(!rt)
{
NewNode(rt);
val[rt]=key;
L=R=0;
size[rt]=cnt[rt]=1;
aux[rt]=(rand()<<14)+rand();
return;
}
if(key<=val[rt])
{
insert(L,key);
if(aux[L]<aux[rt])
rotate(rt,1);
}
else if(key>val[rt])
{
insert(R,key);
if(aux[R]<aux[rt])
rotate(rt,0);
}
pushup(rt);
}
void treap_delete(int &rt)
{
if(!L||!R)
{
rt=L?L:R;
}
else
{
if(aux[L]<aux[R])
{
rotate(rt,1);
treap_delete(R);
}
else
{
rotate(rt,0);
treap_delete(L);
}
}
}
void del(int &rt,int key)
{
if(!rt) return;
if(key==val[rt])
{
cnt[rt]--;
size[rt]--;
if(cnt[rt]==0)
{
Node[tot1++]=rt;
treap_delete(rt);
}
}
else
{
if(key<val[rt])
del(L,key);
else
del(R,key);
size[rt]--;
}
}
int find(int rt,int key)
{
if(!rt) return -1;
else if(key<val[rt]) return find(L,key);
else if(key>val[rt]) return find(R,key);
else return rt;
}
void succ(int rt,int key,int &ans)
{
if(!rt) return;
if(val[rt]>=key)
{
ans=val[rt];
succ(L,key,ans);
}
else
succ(R,key,ans);
}
void pre(int rt,int key,int &ans)
{
if(!rt) return;
if(val[rt]<=key)
{
ans=val[rt];
pre(R,key,ans);
}
else
pre(L,key,ans);
}
int getmin(int rt)
{
while(L)
rt=L;
return val[rt];
}
int getmax(int rt)
{
while(R)
rt=R;
return val[rt];
}
int find_kth(int rt,int k)
{
if(!rt) return 0;
if(k>size[R]+cnt[rt])
return find_kth(L,k-cnt[rt]-size[R]);
else if(k<=size[R])
return find_kth(R,k);
return val[rt];
}
} tree[21111];
int a[N],b[N],f[N];
int type[N],x[N],y[N];
char op[14];
int n,m,q;
bool ok[N];
inline int find(int n)
{
return f[n]!=n?f[n]=find(f[n]):n;
}
inline void dfs(int rt,int u)
{
if(L)
dfs(L,u);
if(R)
dfs(R,u);
tree[u].insert(tree[u].rt,val[rt]);
}
inline void merge(int u,int v)
{
f[v]=u;
dfs(tree[v].rt,u);
}
int main()
{
int i;
int cas=0;
while(~scanf("%d%d",&n,&m)&&(n|m))
{
tot=tot1=0;
for(i=1;i<=n;++i) f[i]=i;
for(i=1;i<=n;++i) scanf("%d",weight+i);
for(i=1;i<=m;++i) scanf("%d%d",a+i,b+i),ok[i]=true;
q=0;
for(i=1;;++i)
{
scanf("%s",op);
if(op[0]=='E') break;
if(op[0]=='D')
{
type[i]=1;
scanf("%d",x+i);
ok[x[i]]=false;
}
else if(op[0]=='Q')
{
type[i]=2;
scanf("%d%d",x+i,y+i);
}
else
{
type[i]=3;
int tmp;
scanf("%d%d",x+i,y+i);
tmp=weight[x[i]];
weight[x[i]]=y[i];
y[i]=tmp;
}
}
q=i-1;
int u,v;
for(i=1;i<=m;++i)
{
if(ok[i])
{
u=find(a[i]);
v=find(b[i]);
if(u!=v)
{
f[u]=v;
}
}
}
int r1,r2;
double ans=0;
int Ccnt=0;
for(i=1;i<=n;++i) tree[i].init(),find(f[i]);
for(i=1;i<=n;++i)
{
u=find(f[i]);
tree[u].insert(tree[u].rt,weight[i]);
}
for(i=q;i>=1;--i)
{
if(type[i]==1)
{
u=a[x[i]];
v=b[x[i]];
u=find(u);
v=find(v);
if(u!=v)
{
r1=tree[u].rt;
r2=tree[v].rt;
if(size[r1]>=size[r2])
merge(u,v);
else
merge(v,u);
}
}
if(type[i]==2)
{
u=find(x[i]);
Ccnt++;
double tmp=0;
if(y[i]<=0||y[i]>size[tree[u].rt])
tmp=0;
else
tmp=tree[u].find_kth(tree[u].rt,y[i]);
ans+=tmp;
}
if(type[i]==3)
{
u=find(x[i]);
tree[u].del(tree[u].rt,weight[x[i]]);
weight[x[i]]=y[i];
tree[u].insert(tree[u].rt,weight[x[i]]);
}
}
if(Ccnt)
ans=ans/Ccnt;
printf("Case %d: %.6f\n",++cas,ans);
}
return 0;
}
hdu 3726 Graph and Queries
最新推荐文章于 2022-11-30 09:52:28 发布