3065: K small value with insertion interval Time limit:60 Sec Memory limit:512 MB
submit:3617 solved:1173
[Submit] [Status] [Discuss] Description
Once there were n fleas lined up to do morning exercises, and each flea had a bounce force of its own a[i]. The Flea King was delighted to see these flea states flourish. Then the flea king decided to be rational and pleasant, query the interval k small value. Every time he asked his attendant Volt to ask the question: From left to right, from X to Y fleas, a[i] K small value is what.
It's hard not to fall in, he's in his head. Using Functional line segment tree prefixes and methods water dropped the flea king's inquiry.
At this point the Volt found some fleas jump for a long time, the bounce force will change, some will increase, some will decrease.
It's hard not to fall, he's in his head using a tree-shaped array of line segments the water dropped the Flea king's inquiry. (Orz Chairman Tree)
The Volt found that some late fleas would be plugged into a position in the line, and he was very angry because ... He won't do it.
Could you help a bunch of volts, please?
Express version Test instructions: With insert, modified interval k small value online query.
Input
The first line is a positive integer n, indicating that there are n fleas lined up to do morning exercises.
The second line has n spaces separated by a non-negative integer, from left to right represents the bounce force of each flea.
The third line is a positive integer q, which indicates how many operations are below.
The following altogether Q line, altogether three kinds of operations to the operation of the original sequence: (assuming at this time altogether m fleas)
1. Q x y K: Ask from left to right X flea to the left to right of the Y flea, jumping force K small Flea Bounce force is how much.
(1 <= x <= y <= m, 1 <= k <= y-x + 1)
2. M x val: Change the bounce force from left to right X Flea to Val.
(1 <= x <= m)
3. I x val: Insert a flea with a jumping force Val in front of the X flea from left to right. That is, after inserting from left to right, the flea is the flea I just inserted.
(1 <= x <= m + 1)
In order to reflect the online operation, set Lastans as the result of the program output at the time of the last query, if not previously queried, then Lastans = 0.
Then the input is actually:
Q _x _y _k------> Express Q _x^lastans _y^lastans _k^lastans
M _x _val------> = M _x^lastans _val^lastans
I _x _val------> Expression I _x^lastans _val^lastans
In simple terms, the integer entered in the operation is different or the result of the last query is decoded.
(I wish Pascal's classmates an early transfer to C + +, will not provide a description of the Pascal version.) )
Output
For each query output answer, one answer per line.
Sample Input 10
10 5 8 28 0 19 2 31 1 22
30
I 6 9
M 1 11
I 8 17
M 1 31
M 6 26
Q 2 7 6
I 23 30
M 31 7
I 22 27
M 26 18
Q 26 17 31
I 5 2
I 18 13
Q 3 3 3
I 27 19
Q 23 23 30
Q 5 13 5
I 3 0
M 15 27
Q 0 28 13
Q 3 29 11
M 2 8
Q 12 5 7
I 30 19
M 11 19
Q 17 8 29
M 29 4
Q 3 0 12
I 7 18
M 29 27
Sample Output 28
2
31
0
14
15
14
27
15
14
HINT
This problem as a small research to do it ~ practice a lot ~ do not know how many ways this problem.
Please consciously O (log^2n), I deliberately card block list, block chain a out of my affectionate one worship ...
A dropped students please in the discuss inside briefly say their own practice it ~
Original sequence length <= 35000
Number of inserts <= 35000, number of modifications <= 70000, query number <= 70000, 0 <= every moment of weight <= 70000
Because it is a problem on the OJ, the data has no gradient. To prevent card OJ, there are only 4 sets of data.
To exercise code Force ... To master the Scapegoat tree ...
Wrote this. Bzoj 3065: With insertion interval K small value think this should be a good question.
If you don't have an insert, you can use a tree-shaped array. Chairman Tree Happy Water
But this insertion is really ...
All right, no nonsense.
We consider what needs to be maintained, obviously the interval and weights.
Interval with line segment tree is very GG, so our choice should be only the balance tree
And we're going to have to maintain the right value information. The line tree is a great choice.
So at the end of the balance tree is the set of weight line tree
First consider the insertion, if the use of treap splay words need to rotate, to directly maintain the sequence relationship seems to be very unreliable change information after each rotation is not very good
So consider using a more worrying approach--making the balance tree not spinning
This time fully demonstrated the superiority of scapegoat tree run fast without rotation (that is, the code is a little long lost)
Because it doesn't have to be rotated, it uses a violent refactoring approach
So you can better control the merging of information
The BJ code uses a violent refactoring to add the elements that are expected in each segment tree in each node
So the complexity of every violent refactoring is obviously nlog^2n.
Each node expects to refactor Logn times
So refactoring complexity is nlog^3n
It's a lot easier to ask.
Find all segment trees and nodes corresponding to the interval in the balance tree (do not understand the code)
Just two minutes later.
Complexity of QLOG^2N
So the end is nlog^3n.
So it is not possible to make the complexity more difficult by the solution of the tree of the weight line in this equilibrium tree.
Let's consider the complexity of refactoring.
Every refactoring is nlog^2n, that's not beautiful.
How to optimize it out.
Well, the line segment tree merges. (Merging N of line-tree complexity with only a single weight value is Nlogn)
So the optimization is complete haha
But because the code is a little lazy BJ has adopted the time complexity of the high-end method for code complexity ....
Code output debugging a bit more not deleted. I'm so weak.
#include <cmath> #include <ctime> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <iomanip> #include <vector> #include <
string> #include <bitset> #include <queue> #include <map> #include <set> using namespace std;
typedef double DB;
inline int read () {int X=0,f=1;char ch=getchar (); while (ch< ' 0 ' | |
Ch> ' 9 ') {if (ch== '-') F=-1;ch=getchar ();}
while (ch<= ' 9 ' &&ch>= ' 0 ') {x= (x<<1) + (x<<3) +ch-' 0 '; Ch=getchar ();}
return x*f;
} void print (int x) {if (x<0) Putchar ('-'), X=-x;if (x>=10) print (X/10);p Utchar (x%10+ ' 0 ');}
const int n=70010,m=10000100;
Const DB alpha=0.75;
int n,root,rt[n]; struct Scapegoat_tree{int fa,s[2],val;}
Tr[n]; struct Seg_tree{int ls,rs,w;}
STR[M];
int Rec[m],btop,node;
inline int NewNode () {return btop?rec[btop--]:++node;}
void Recycle (int &k) {//cout<<k<<endl;
if (!k) return;
Rec[++btop]=k; RecycLe (STR[K].LS); recycle (str[k].rs);
str[k].w=0;k=0;
} void Insert (int &k,int l,int r,int x,int val) {if (!k) K=newnode (); str[k].w+=val;//cout<<k<< "<<l<<" "<<r<<" "<<x<<" <<val
<< "" <<str[k].w<<endl;
if (!STR[K].W) {recycle (k); return;}
if (l==r) return; int mid= (L+R) >>1;
X<=mid?insert (Str[k].ls,l,mid,x,val): Insert (Str[k].rs,mid+1,r,x,val); } inline bool Balance (int k) {return (db (ALPHA*STR[RT[K]].W) >db (STR[RT[TR[K].S[0]]].W)) && (db (Alpha*str[rt [K]].
W) >db (STR[RT[TR[K].S[1]]].W));}
int sta[n],top;
void Seek (int k) {if (!k) return; recycle (rt[k]); Seek (Tr[k].s[0]); Sta[++top]=k;seek (Tr[k].s[1]);}
int build (int l,int r) {if (l>r) return 0;
int mid= (l+r) >>1,now=sta[mid];//cout<<l<< "<<r<<" <<now<<endl;
Tr[now].s[0]=build (l,mid-1);
Tr[now].s[1]=build (MID+1,R);
Tr[tr[now].s[0]].fa=tr[tr[now].s[1]].fa=now; for (int i=l;i<=r;++i) Insert (Rt[now],0,n,tr[sta[i]].val,1);//,cout<<now<< "" <<tr[sta[i]].val<< ":";cout<<endl;
return now;
} void rebuild (int k) {//cout<<k<<endl;cout<< "SDFSDFSDFSDFSDFSFDFDSSFDSDFDSFDF" <<endl;
Top=0;seek (k);
int fa=tr[k].fa,son= (tr[fa].s[1]==k), Now=build (1,top);
TR[FA].S[SON]=NOW;TR[NOW].FA=FA;
if (k==root) Root=now;
} void Insert (int &k,int x,int Y,int fa) {if (!k) {k=++n;
TR[K].VAL=Y;TR[K].FA=FA;
int INV=0,TMP=FA;
while (TMP) {if (!balance (TMP)) Inv=tmp;tmp=tr[tmp].fa;}
Inv?rebuild (INV): Insert (rt[k],0,n,y,1);
return;
} insert (rt[k],0,n,y,1);
int TMP=STR[RT[TR[K].S[0]]].W;
X<=tmp?insert (tr[k].s[0],x,y,k): Insert (TR[K].S[1],X-TMP-1,Y,K); } int Modify (int k,int x,int y) {//cout<<k<< "<<x<<" "<<y<<" FDAs "<<endl;if
(!k) exit (0);
Insert (rt[k],0,n,y,1);
int SON=STR[RT[TR[K].S[0]]].W;
if (x==son+1) {int tmp=tr[k].val;
Tr[k].val=y; Insert (rt[k],0,n,tmp,-1);//COUT<<TMP≪< "" <<y<< "DGSF" <<endl;
return TMP;
} int tmp= (X<=son?modify (tr[k].s[0],x,y): Modify (tr[k].s[1],x-son-1,y));//cout<<tmp<<endl;
Insert (RT[K],0,N,TMP,-1);
return TMP;
} int s[n],p[n],stop,ptop;
void find_seg (int k,int l,int r) {int ls=tr[k].s[0],rs=tr[k].s[1];
if (L==1&&R==STR[RT[K]].W) {S[++stop]=rt[k];return;}
if (l<=str[rt[ls]].w+1&&r>=str[rt[ls]].w+1) {p[++ptop]=k;}
if (R<=STR[RT[LS]].W) find_seg (ls,l,r);
else if (l>str[rt[ls]].w+1) find_seg (rs,l-str[rt[ls]].w-1,r-str[rt[ls]].w-1);
else {if (L<=STR[RT[LS]].W) find_seg (LS,L,STR[RT[LS]].W);
if (r>str[rt[ls]].w+1) find_seg (rs,1,r-str[rt[ls]].w-1);
}} int query (int x,int y,int k) {ptop=stop=0;find_seg (root,x,y); Register int l=0,r=n,mid,i,sum;//for (i=1;i<=ptop;++i) cout<<tr[p[i]].val<< "";cout<<endl<
<endl;
while (L<r) {mid= (l+r) >>1;sum=0;
for (i=1;i<=stop;++i) SUM+=STR[STR[S[I]].LS].W; for (i=1;i<=ptop;++i) sum+= (tr[p[i]].val<=mid&&tr[p[i]].val>=l);//cout<<l<< "" <<r<< "" <<
mid<< "" <<sum<<endl;
if (sum<k) {for (i=1;i<=stop;++i) s[i]=str[s[i]].rs;
k-=sum;l=mid+1;
} else {for (i=1;i<=stop;++i) s[i]=str[s[i]].ls;
R=mid;
}} return L;
} int main () {n=read ();
register int i,k,ans=0,x,y;
for (i=1;i<=n;++i) {tr[i].val=read (); tr[i].fa=i-1;tr[i-1].s[1]=i;} if (n) {root=1;rebuild (root);}
cout<< "SFD" <<endl;
int Q=read ();
Char opt[2];
while (q--) {scanf ("%s", opt);
X=read () ^ans;y=read () ^ans;//cout<<str[rt[root]].w<< "DFSSDF" <<endl;
Switch (opt[0]) {case ' Q ': K=read () ^ans;ans=query (x,y,k);p rint (ANS);p UTS ("");
Case ' M ': Modify (Root,x,y);
Case ' I ': Insert (root,x-1,y,0); }//for (i=1;i<=n;++i) cout<<tr[i].val<< "" <<tr[i].s[0]<< "" <<tr[i].s[1]<< ""
<<str[rt[i]].w<<endl;
} return 0; }/* 10
5 8 (0) 2 1 6 I 9 1 M 8 one I 1 M 6 2 M 7 (q 6) 7 I, 5 m, I, M, 2 Q, 1
8 Q 3 3 3 I (q) 5 q 5 3 I 0 0 M 3 2 q 8 5 Q/A 7/(8) M 29 4 (m) Q 3 0 I 7 M 29 27 28 2 31 0 14 15 14 27 15 14 * *