[CODEVS3032] placement ball problem solving report, codevs3032 Problem Solving
I tried to use this question in a heap. I didn't practice the heap, But I practiced the line segment tree.
This question belongs to the kind of things that seem very simple. It was just like making A splash. I made it six times and it took N years to get A beat.
Note the following points:
1. What information does the node save?
In the question, the greatest distance is obtained, but this is not easy in the online segment tree;
At first, I took it for granted the r-l distance, and it was time to merge the information.
It is better to save the number of consecutive empty shards in the interval:① When setting the meaning of variables, you must start from the perspective of ease of understanding and debugging.
Obviously, the left and right endpoints of the longest continuous interval also need to be saved, because we need to use it to find out where the ball should be placed. But! If the length of an interval is 0, where should the Left and Right endpoints be?
2,② If the length of [l, r] is 0, l = r + 1, r = L-1.
Why? Let's see what we did during the merger?
Set struct TS {int lmax, lR, rmax, rL, max, L, R}
If (tree [node <1]. lR = (l + r)> 1) + 1 ){
Tree [node]. lmax + = tree [node <1 | 1]. lmax;
Tree [node]. lR = tree [node <1 | 1]. lR;
}
What happens if tree [node <1 | 1]. lmax = 0?
If tree [node <1 | 1]. lR = (l + r)> 1 is set
Tree [node <1]. lR = (l + r)> 1.
Is correct.
So .. That's it.
3,③ Which of the three variables should be the largest?
It is easy to confuse ..
Clear organization?
List all the conditions!
If (a> = B & a> = c ){}
If (B> = a & B> = c ){}
If (c >=a & c >= B ){}
4. Where should I put the ball?
Obviously, the ball should be placed in the longest continuous interval without the ball, .. Where is it?
Set the interval [L, R] to a maximum continuous subinterval without a ball, and L> 1, R <N.
Obviously④ The ball should be placed in the L-1 and R + 1 median position, in order to make the ball and L-1 and R + 1 Distance of the minimum value of the maximum.
That is, x = (L-1 + R + 1)> 1 = (L + R)> 1.
5,⑤ Special Interval?
The range extending from 1 to right and the range extending from N to left. The distance length of the ball here is the interval length!
6. max?
At this time, we found a big problem! It is the max record in the node. It is not the shortest distance. The shortest distance should be max + 1> 1!
That is to say, if we compare the values by max, we will always select the one on the left when max is the largest, it is likely that only 1 is smaller than the currently selected max, and its + 1> 1 is the same as the currently selected max, and the max on the right is missed, leading to all losses!
However, if we do not select max, is it possible that the selected max is relatively small, so that the max after synthesis is smaller than the actually selected max? That is to say, a max difference of 1 is not counted, but two differences of 2 are different!
But we suddenly found a problem! Max will not be merged. The only operation related to max is Cmp. Merging is performed by lmax and rmax, while lmax and rmax do not need Cmp!
So .. After countless times of WA and WTI, we finally found the correct solution ..
#include<iostream>using namespace std;#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>struct TS{int lmax,rmax,max,L,R,lR,rL;}tree[800000];int point[1000001];#define root 1,1,N#define lson node<<1,l,(l+r)>>1#define rson node<<1|1,((l+r)>>1)+1,rinline void update(int node,int l,int r,int x,int A){if(l==r)if(A)tree[node]=(TS){1,1,1,x-1,x+1,x+1,x-1};else tree[node]=(TS){0,0,0,r,l,l,r};else{int m=(l+r)>>1;if(x>m)update(rson,x,A);else update(lson,x,A);tree[node].lmax=tree[node<<1].lmax;if(tree[node<<1].lR==m+1){tree[node].lmax+=tree[node<<1|1].lmax;tree[node].lR=tree[node<<1|1].lR;}else tree[node].lR=tree[node<<1].lR;tree[node].rmax=tree[node<<1|1].rmax;if(tree[node<<1|1].rL==m){tree[node].rmax+=tree[node<<1].rmax;tree[node].rL=tree[node<<1].rL;}else tree[node].rL=tree[node<<1|1].rL;int tmp=tree[node<<1].rmax+tree[node<<1|1].lmax;if(tree[node<<1].max+1>>1>=tree[node<<1|1].max+1>>1&&tree[node<<1].max+1>>1>=tmp+1>>1){tree[node].max=tree[node<<1].max;tree[node].L=tree[node<<1].L;tree[node].R=tree[node<<1].R;}elseif(tmp+1>>1>=tree[node<<1].max+1>>1&&tmp+1>>1>=tree[node<<1|1].max+1>>1){tree[node].max=tmp;tree[node].L=tree[node<<1].rL;tree[node].R=tree[node<<1|1].lR;}else{tree[node].max=tree[node<<1|1].max;tree[node].L=tree[node<<1|1].L;tree[node].R=tree[node<<1|1].R;}}//cout<<l<<","<<r<<":"<<tree[node].max<<"("<<tree[node].L<<"->"<<tree[node].R<<")"<<" "<<tree[node].lmax<<"("<<l<<"->"<<tree[node].lR<<")"<<" "<<tree[node].rmax<<"("<<tree[node].rL<<"<-"<<r<<")\n";}inline void build(int node,int l,int r){tree[node]=(TS){r-l+1,r-l+1,r-l+1,l-1,r+1,r+1,l-1};if(l!=r)build(lson),build(rson);}inline void out(int node,int l,int r){if(l!=r)out(lson),out(rson);else cout<<!tree[node].max;}int main(){freopen("CODEVS3032.in","r",stdin);//freopen("CODEVS3032.out","w",stdout);memset(tree,0,sizeof(tree));int N,M,flag,A,x,tot=0,l,m,r;scanf("%d%d",&N,&M);build(root);while(M--){scanf("%d%d",&flag,&A);if(flag-1)update(root,point[A],1);else{//cout<<tree[1].lmax<<" "<<(tree[1].max+1>>1)<<" "<<tree[1].rmax<<endl;if(tree[1].lmax>=tree[1].rmax&&tree[1].lmax>=tree[1].max+1>>1)x=1;elseif(tree[1].max+1>>1>=tree[1].rmax&&tree[1].max+1>>1>=tree[1].lmax)x=(tree[1].L+tree[1].R)>>1;else x=N;printf("%d\n",x);update(root,x,0);point[A]=x;}/*cout<<flag<<" "<<A<<":";out(root);cout<<endl;*/}}
7. important conclusion: No matter how simple a question is, be sure to write a correct picture! Half of the questions are all taken! Many questions seem simple, but not easy.