魔法少女LJJ

思路:

  动态开点权值线段树+启发式合并;

来,上代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define maxn 400005
#define maxm 7000000 int ch[maxm][],X,dis[maxm],tot,n,ai[maxn];
int size,f[maxn],cnt,op[maxn],x[maxn],y[maxn],root[maxn]; double lo[maxm],logg[maxn],XX; inline int lower_bound(int pos)
{
int l=,r=size,mid,res;
while(l<=r)
{
mid=l+r>>;
if(pos>=ai[mid]) l=(res=mid)+;
else r=mid-;
}
return res;
} inline void in(int &now)
{
char Cget=getchar();now=;
while(Cget>''||Cget<'') Cget=getchar();
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
} void tree_query(int now,int l,int r,int li,int ri)
{
if(!dis[now]) return ;
if(l==r)
{
X+=dis[now],dis[now]=,lo[now]=;
return ;
}
int mid=l+r>>;
if(li<=mid) tree_query(ch[now][],l,mid,li,ri);
if(ri>mid) tree_query(ch[now][],mid+,r,li,ri);
dis[now]=dis[ch[now][]]+dis[ch[now][]],lo[now]=lo[ch[now][]]+lo[ch[now][]];
} void tree_add(int &now,int l,int r,int to)
{
if(!now) now=++tot;
dis[now]+=X,lo[now]+=XX;
if(l==r) return ;
int mid=l+r>>;
if(to<=mid) tree_add(ch[now][],l,mid,to);
else tree_add(ch[now][],mid+,r,to);
} int merge(int now,int pre,int l,int r)
{
if(!now) return pre;
if(!pre) return now;
if(l==r)
{
lo[now]+=lo[pre];
dis[now]+=dis[pre];
return now;
}
int mid=l+r>>;
ch[now][]=merge(ch[now][],ch[pre][],l,mid);
ch[now][]=merge(ch[now][],ch[pre][],mid+,r);
lo[now]=lo[ch[now][]]+lo[ch[now][]];
dis[now]=dis[ch[now][]]+dis[ch[now][]];
return now;
} int irank(int now,int k)
{
int l=,r=size,mid;
while(l<r)
{
mid=l+r>>;
if(dis[ch[now][]]>=k) r=mid,now=ch[now][];
else k-=dis[ch[now][]],l=mid+,now=ch[now][];
}
return ai[l];
} inline int find(int j)
{
return f[j]==j?j:f[j]=find(f[j]);
} int main()
{
in(n);
for(int i=;i<=n;i++)
{
in(op[i]),in(x[i]);
if(op[i]>&&op[i]<) in(y[i]);
if(op[i]==) ai[++size]=x[i];
if(op[i]==||op[i]==) ai[++size]=y[i];
}
sort(ai+,ai+size+),size=unique(ai+,ai+size+)-ai-;
for(int i=;i<=size;i++) logg[i]=log(ai[i]);
for(int i=;i<=n;i++)
{
if(op[i]==) x[i]=lower_bound(x[i]),X=,XX=logg[x[i]],tree_add(root[++cnt],,size,x[i]),f[cnt]=cnt;
else if(op[i]==)
{
x[i]=find(x[i]),y[i]=find(y[i]);
if(x[i]==y[i]) continue;
root[y[i]]=merge(root[x[i]],root[y[i]],,size),f[x[i]]=y[i];
}
else if(op[i]==)
{
y[i]=lower_bound(y[i]),x[i]=find(x[i]),X=;
if(y[i]>) tree_query(root[x[i]],,size,,y[i]-),XX=logg[y[i]]*X;
if(X) tree_add(root[x[i]],,size,y[i]);
}
else if(op[i]==)
{
y[i]=lower_bound(y[i]),x[i]=find(x[i]),X=;
if(y[i]<size) tree_query(root[x[i]],,size,y[i]+,size),XX=logg[y[i]]*X;
if(X) tree_add(root[x[i]],,size,y[i]);
}
else if(op[i]==) printf("%d\n",irank(root[find(x[i])],y[i]));
else if(op[i]==) puts(lo[root[find(x[i])]]>lo[root[find(y[i])]]?"":"");
else if(op[i]==) printf("%d\n",dis[root[find(x[i])]]);
else printf("Orz\n");
}
return ;
}
05-11 22:08