算法竞赛从此变为读题竞赛
c<=7
话说加上 8 9 可做么...
大数比大小 用对数
然后就是递归线段树的一些操作了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
int n;
int size,root[400005],fat[400005];
int sum[6000005],ls[6000005],rs[6000005];
double loog[6000005];
namespace Memory{
int Stack[6000005],top;
inline void init(){
for (int i=6000000;i;i--) Stack[++top]=i;
}
inline int New(){
return Stack[top--];
}
inline void Del(int u){
Stack[++top]=u;
sum[u]=loog[u]=0; ls[u]=rs[u]=0;
}
inline int getfat(int u){
return fat[u]==u?u:fat[u]=getfat(fat[u]);
}
}
using namespace Memory;
int sx[400005];
int icnt;
inline int Bin(int x){
return lower_bound(sx+1,sx+icnt+1,x)-sx;
}
inline int update(int u){
loog[u]=loog[ls[u]]+loog[rs[u]];
sum[u]=sum[ls[u]]+sum[rs[u]];
}
inline void insert(int &u,int l,int r,int x,int num)
{
if (!u) u=New();
if (l==r){
loog[u]+=num*log(sx[x]);
sum[u]+=num;
return;
}
int mid=(l+r)>>1;
if (x<=mid)
insert(ls[u],l,mid,x,num);
else
insert(rs[u],mid+1,r,x,num);
update(u);
}
inline void clear(int &u,int l,int r,int a,int b){
if (a==l && b==r)
{
Del(u),u=0;
return;
}
int mid=(l+r)>>1;
if (b<=mid)
clear(ls[u],l,mid,a,b);
else if (mid+1<=a)
clear(rs[u],mid+1,r,a,b);
else
clear(ls[u],l,mid,a,mid),clear(rs[u],mid+1,r,mid+1,b);
update(u);
}
inline int query(int u,int l,int r,int a,int b)
{
if (a==l && b==r) return sum[u];
int mid=(l+r)>>1;
if (b<=mid)
return query(ls[u],l,mid,a,b);
else if (mid+1<=a)
return query(rs[u],mid+1,r,a,b);
else
return query(ls[u],l,mid,a,mid)+query(rs[u],mid+1,r,mid+1,b);
}
inline int rank(int &u,int l,int r,int k)
{
if (l==r) return l;
int mid=(l+r)>>1;
if (k<=sum[ls[u]])
return rank(ls[u],l,mid,k);
else
return rank(rs[u],mid+1,r,k-sum[ls[u]]);
}
inline int merge(int x,int y)
{
if (!x) return y;
if (!y) return x;
ls[x]=merge(ls[x],ls[y]);
rs[x]=merge(rs[x],rs[y]);
update(x);
return x;
}
struct event{
int c,a,b;
}eve[400005];
int main()
{
init();
int Q,order,itmp,ans,u,v,k,x,fx,fy;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(Q);
for (int i=1;i<=Q;i++)
{
read(eve[i].c);
if (eve[i].c==1)
read(eve[i].b),sx[++icnt]=eve[i].b;
else if (eve[i].c==3 || eve[i].c==4)
read(eve[i].a),read(eve[i].b),sx[++icnt]=eve[i].b;
else if (eve[i].c==7)
read(eve[i].a);
else
read(eve[i].a),read(eve[i].b);
}
sort(sx+1,sx+icnt+1);
icnt=unique(sx+1,sx+icnt+1)-sx-1;
for (int i=1;i<=Q;i++)
{
if (eve[i].c==1)
{
++n; fat[n]=n;
x=Bin(eve[i].b);
insert(root[fat[n]],1,icnt,x,1);
}
else if (eve[i].c==2)
{
u=eve[i].a; v=eve[i].b;
fx=getfat(u); fy=getfat(v);
if (fx!=fy)
{
fat[fx]=fy;
root[fy]=merge(root[fx],root[fy]);
}
}
else if (eve[i].c==3)
{
u=getfat(eve[i].a); x=Bin(eve[i].b);
if (x==1) continue;
itmp=query(root[u],1,icnt,1,x-1);
insert(root[u],1,icnt,x,itmp);
clear(root[u],1,icnt,1,x-1);
}
else if (eve[i].c==4)
{
u=getfat(eve[i].a); x=Bin(eve[i].b);
if (x==icnt) continue;
itmp=query(root[u],1,icnt,x+1,icnt);
insert(root[u],1,icnt,x,itmp);
clear(root[u],1,icnt,x+1,icnt);
}
else if (eve[i].c==5)
{
u=getfat(eve[i].a); k=eve[i].b;
ans=sx[rank(root[u],1,icnt,k)];
printf("%d\n",ans);
}
else if (eve[i].c==6)
{
u=getfat(eve[i].a); v=getfat(eve[i].b);
ans=loog[root[u]]>loog[root[v]]?1:0;
printf("%d\n",ans);
}
else if (eve[i].c==7)
{
u=getfat(eve[i].a);
ans=sum[root[u]];
printf("%d\n",ans);
}
}
return 0;
}