# 题解：

Orz vfleaking……真·神题

ps：貌似我写的替罪羊是假的……rebuild的地方会重复rec很多次……alpha小了会T，大了会WA……经过面对oj调参+玄学读优才卡时限过……

# 代码：

1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 1000000007
8 #define eps 1e-9
9 using namespace std;
10 typedef long long ll;
11 typedef double db;
12 const db alpha=0.865;
13 int n,m,l,r,k,rt=0,cur,cnt=0,top=0,nw[500001],st[500001];
14 db s[500001];
15 char op[3];
16 struct num{
17     int x,y;
18     num(){}
19     num(int _x,int _y){
20         x=_x,y=_y;
21     }
22     friend bool operator ==(num a,num b){
23         return a.x==b.x&&a.y==b.y;
24     }
25     friend bool operator <(num a,num b){
26         return a.x==b.x?s[a.y]<s[b.y]:s[a.x]<s[b.x];
27     }
28 };
29 struct node{
30     int ls,rs,siz;
31     //db s;
32     num v;
33 }t[500001];
34 struct _node{
35     int v,p;
36 }tr[500001];
37 char buffer[6000010],*hd,*tl;
38 inline char Getchar(){
39     if(hd==tl){
41         hd=buffer,tl=hd+len;
42         if(hd==tl)
43             return EOF;
44     }
45     return *hd++;
46 }
47 inline int rd(){
48     register int x=0,f=1;
49     char c;
50     do{
51         c=Getchar();
52         if(c=='-')f=-1;
53     }while(!isdigit(c));
54     do{
55         x=(x<<1)+(x<<3)+(c^48);
56         c=Getchar();
57     }while(isdigit(c));
58     return x*f;
59 }
60 void getmx(num &a,num b){
61     if((a.y==b.y&&a.x>b.x)||s[a.y]<s[b.y])a=b;
62 }
63 bool ndrb(int u){
64     return t[t[u].ls].siz>t[u].siz*alpha+5||t[t[u].rs].siz>t[u].siz*alpha+5;
65 }
66 void rec(int u){
67     if(t[u].ls)rec(t[u].ls);
68     st[++top]=u;
69     if(t[u].rs)rec(t[u].rs);
70 }
71 void rebuild(int &u,int l,int r,db L,db R){
72     int mid=(l+r)/2;
73     db Mid=(L+R)/2;
74     u=st[mid];
75     s[u]=Mid;
76     t[u].ls=t[u].rs=0;
77     if(l<mid)rebuild(t[u].ls,l,mid-1,L,Mid);
78     if(mid<r)rebuild(t[u].rs,mid+1,r,Mid,R);
79     t[u].siz=t[t[u].ls].siz+t[t[u].rs].siz;
80 }
81 void rb(int &u,db L,db R){
82     top=0;
83     rec(u);
84     rebuild(u,1,top,L,R);
85 }
86 int ins(int &u,db L,db R,num x){
87     db Mid=(L+R)/2;
88     if(!u){
89         u=++cnt;
90         t[u].v=x;
91         s[u]=Mid;
92         t[u].ls=t[u].rs=0;
93         t[u].siz=1;
94         return u;
95     }
96     t[u].siz++;
97     if(ndrb(u))rb(u,L,R);
98     if(x==t[u].v)return u;
99     else if(x<t[u].v)return ins(t[u].ls,L,Mid,x);
100     else return ins(t[u].rs,Mid,R,x);
101 }
102 void pushup(int u){
103     if(tr[u*2].v==tr[u*2+1].v||s[tr[u*2].v]>s[tr[u*2+1].v]){
104         tr[u].v=tr[u*2].v;
105         tr[u].p=tr[u*2].p;
106     }else{
107         tr[u].v=tr[u*2+1].v;
108         tr[u].p=tr[u*2+1].p;
109     }
110 }
111 void build(int l,int r,int u){
112     tr[u].v=1;
113     tr[u].p=l;
114     if(l==r)return;
115     int mid=(l+r)/2;
116     build(l,mid,u*2);
117     build(mid+1,r,u*2+1);
118 }
119 void updata(int l,int r,int u,int p){
120     if(l==r){
121         tr[u].v=nw[l];
122         tr[u].p=l;
123         return;
124     }
125     int mid=(l+r)/2;
126     if(p<=mid)updata(l,mid,u*2,p);
127     else updata(mid+1,r,u*2+1,p);
128     pushup(u);
129 }
130 num query(int l,int r,int u,int L,int R){
131     if(L<=l&&r<=R){
132         return num(tr[u].p,tr[u].v);
133     }
134     int mid=(l+r)/2;
135     num ret(0,0);
136     if(L<=mid)getmx(ret,query(l,mid,u*2,L,R));
137     if(mid<R)getmx(ret,query(mid+1,r,u*2+1,L,R));
138     return ret;
139 }
140 int main(){
141     #ifndef ONLINE_JUDGE
142     freopen("10.in","r",stdin);
143     freopen("my.out","w",stdout);
144     #endif
145     //scanf("%d%d",&n,&m);
146     n=rd(),m=rd();
147     cur=ins(rt,0,1,num(1,0));
148     for(int i=1;i<=n;i++)nw[i]=cur;
149     build(1,n,1);
150     for(int i=1;i<=m;i++){
151         //scanf("%s%d%d",op,&l,&r);
152         char ch;
153         ch=Getchar();
154         while(ch!='C'&&ch!='Q')ch=Getchar();
155         l=rd(),r=rd();
156         if(ch=='C'){
157             //scanf("%d",&k);
158             k=rd();
159             nw[k]=ins(rt,0,1,num(nw[l],nw[r]));
160             updata(1,n,1,k);
161         }else printf("%d\n",query(1,n,1,l,r).x);
162     }
163     return 0;
164 }
posted @ 2019-01-10 21:32 DCDCBigBig 阅读(...) 评论(...) 编辑 收藏