[BZOJ4399]魔法少女LJJ(线段树合并)

请仔细阅读数据范围,c<=7.
线段树合并裸题,对于乘积大小比较,使用log即可。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define lson ls[x],L,mid
 6 #define rson rs[x],mid+1,R
 7 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 8 using namespace std;
 9 
10 const int N=400010,K=N*16,M=1000000000;
11 int Q,op,n,x,y,k,nd,rt[N],fa[N],sz[K],ls[K],rs[K];
12 double sm[K];
13 
14 int get(int x){ return (fa[x]==x) ? x : fa[x]=get(fa[x]); }
15 
16 void ins(int &x,int L,int R,int pos,int k){
17     if (!x) x=++nd;
18     if (L==R){ sz[x]+=k; sm[x]+=k*log(L); return; }
19     int mid=(L+R)>>1;
20     if (pos<=mid) ins(lson,pos,k); else ins(rson,pos,k);
21     sz[x]=sz[ls[x]]+sz[rs[x]]; sm[x]=sm[ls[x]]+sm[rs[x]];
22 }
23 
24 int mdf0(int &x,int L,int R,int k){
25     if (!x) return 0;
26     if (L==R){ if (k>L) { x=0; return 1; } else return 0; }
27     int mid=(L+R)>>1,res=0;
28     if (k>mid) res+=sz[ls[x]],ls[x]=0,res+=mdf0(rson,k);
29         else res=mdf0(lson,k);
30     sz[x]=sz[ls[x]]+sz[rs[x]]; sm[x]=sm[ls[x]]+sm[rs[x]];
31     return res;
32 }
33 
34 int mdf1(int &x,int L,int R,int k){
35     if (!x) return 0;
36     if (L==R){ if (k<L) { x=0; return 1; } else return 0; }
37     int mid=(L+R)>>1,res=0;
38     if (k<=mid) res+=sz[rs[x]],rs[x]=0,res+=mdf1(lson,k);
39         else res=mdf1(rson,k);
40     sz[x]=sz[ls[x]]+sz[rs[x]]; sm[x]=sm[ls[x]]+sm[rs[x]];
41     return res;
42 }
43 
44 int merge(int x,int y,int L,int R){
45     if (!x || !y) return x+y;
46     sz[x]+=sz[y]; sm[x]+=sm[y];
47     if (L<R){
48         int mid=(L+R)>>1;
49         ls[x]=merge(ls[x],ls[y],L,mid);
50         rs[x]=merge(rs[x],rs[y],mid+1,R);
51     }
52     return x;
53 }
54 
55 int find(int x,int L,int R,int k){
56     if (L==R) return L;
57     int mid=(L+R)>>1;
58     if (k<=sz[ls[x]]) return find(lson,k);
59         else return find(rson,k-sz[ls[x]]);
60 }
61 
62 int main(){
63     freopen("bzoj4399.in","r",stdin);
64     freopen("bzoj4399.out","w",stdout);
65     for (scanf("%d",&Q); Q--; ){
66         scanf("%d",&op);
67         if (op==1) scanf("%d",&x),n++,fa[n]=n,ins(rt[n],1,M,x,1);
68         if (op==2){
69             scanf("%d%d",&x,&y); int p=get(x),q=get(y);
70             if (p==q) continue;
71             rt[p]=merge(rt[p],rt[q],1,M); fa[q]=p;
72         }
73         if (op==3) scanf("%d%d",&x,&k),ins(rt[get(x)],1,M,k,mdf0(rt[get(x)],1,M,k));
74         if (op==4) scanf("%d%d",&x,&k),ins(rt[get(x)],1,M,k,mdf1(rt[get(x)],1,M,k));
75         if (op==5) scanf("%d%d",&x,&k),printf("%d\n",find(rt[get(x)],1,M,k));
76         if (op==6) scanf("%d%d",&x,&y),printf("%d\n",(int)(sm[rt[get(x)]]>sm[rt[get(y)]]));
77         if (op==7) scanf("%d",&x),printf("%d\n",sz[rt[get(x)]]);
78     }
79     return 0;
80 }

 

posted @ 2018-10-29 23:39  HocRiser  阅读(271)  评论(0编辑  收藏  举报