[线段树 合并] BZOJ 4399 魔法少女LJJ

来源:互联网 发布:沂南知豆租赁服务中心 编辑:程序博客网 时间:2024/05/01 23:52

算法竞赛从此变为读题竞赛

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);elseinsert(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);elseclear(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);elsereturn 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);elsereturn 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;}



0 0
原创粉丝点击