Transmission Door
To do this, we need two predecessors: two-dimensional segment tree and tag permanence.
We use a one-dimensional segment tree to maintain a sequence, and when we want to maintain a matrix, a two-dimensional line segment tree emerges.
Two-dimensional line-segment trees seem to be implemented in both ways. One is for each node (each point on the x-axis) to open another line tree (indicating a y-axis) (This is like more people calling him tree nesting tree practice?). )
The second one is to turn it into a four-pronged tree ... But I did not learn this way of achieving it.
The specific implementation method is actually very good, can choose to write structure. is for a change, normal in our one-dimensional line segment tree upload 6 parameters, we will pass two records of the y-axis modification range of parameters, and then arrive at the time of making the modification position we go to the Y axis to modify. (This can look at the code for a while)
After saying that the tag is permanent, we have to pushdown in the interval modification, but this kind of tree sets tree and so on more complex data structure is very troublesome, and especially like this problem, you do not know how to devolve. So we make the tag permanent. In the case of interval addition, we maintain sum and add two tokens, and add the value of the interval length to the sum of each interval before it is modified to the specified position. Then we add the add value to the interval when we modify it to the specified location (full coverage).
Then in each subsequent query, each time we go down, we have to add this interval to contribute to the add* interval length, this is the result (note that the interval is completely covered when the time is not added, because this is already counted in sum)
Let's look at the problem now. The topic translation is very good, especially concise, and is directly tell you what to do rather than let you summarize again.
We maintain this sequence with a two-dimensional line segment tree. For each modification, we first query the maximum value within the matrix, and then directly change to the maximum +h height of the line.
On the way it is possible to mark the permanent. This idea and the interval addition is the same, but this becomes a permanent maximum value, so at each time the devolution of the current MX (maximum), until the interval completely overwrite update tag (modified maximum), when the query for a range, All query values are compared to the tag of this interval, and then a larger value is returned.
Take a look at the code.
#include <iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<queue>#include<cstring>#defineRep (i,a,n) for (int i = a;i <= n;i++)#definePer (i,n,a) for (int i = n;i >= a;i--)#defineEnter Putchar (' \ n ')#definePR pair<int,int>#defineMP Make_pair#defineFi first#defineSC Secondusing namespaceStd;typedefLong Longll;Const intM =100005;Const intN =8005; intRead () {intAns =0, op =1; CharCH =GetChar (); while(Ch <'0'|| CH >'9') { if(ch = ='-') op =-1; CH=GetChar (); } while(Ch >='0'&& CH <='9') {ans*=Ten; Ans+ = CH-'0'; CH=GetChar (); } returnAns *op;}intd,s,h,x,y,k,n,m;structSegy//Maintain y-axis{ intMx[n],tag[n]; voidChangeintPintLintRintKlintkrintval) {Mx[p]= max (mx[p],val);//Update (token persistence) if(L = = KL && R = =KR) {Tag[p]= max (tag[p],val);//Update when the interval is fully covered return; } intMid = (l+r) >>1;//everything's fine . if(KR <= mid) Change (p<<1, L,mid,kl,kr,val); Else if(KL > Mid) Change (p<<1|1, mid+1, R,kl,kr,val); ElseChange (p<<1, L,mid,kl,mid,val), Change (p<<1|1, mid+1, r,mid+1, Kr,val); } intQueryintPintLintRintKlintKR) { if(L = = KL && r = = KR)returnMX[P];//fully covered intCur = Tag[p],mid = (l+r) >>1;//All that's left is compared to tag. if(KR <= mid) cur = max (query (p<<1, L,MID,KL,KR), cur); Else if(KL > Mid) cur = max (query (p<<1|1, mid+1, R,KL,KR), cur); Elsecur = max (Cur,max (Query (p<<1, L,mid,kl,mid), query (p<<1|1, mid+1, r,mid+1, KR)); returncur; }};structSegx//maintain x-axis{segy mx[n],tag[n]; voidChangeintPintLintRintKlintkrintZlintZrintval) {Mx[p].change (1,1, M,zl,zr,val);//change every time (tags are permanent) if(L = = KL && R = =KR) {Tag[p].change (1,1, M,zl,zr,val);//only full overwrite is modified return; } intMid = (l+r) >>1;//the rest is normal. if(KR <= mid) Change (p<<1, L,mid,kl,kr,zl,zr,val); Else if(KL > Mid) Change (p<<1|1, mid+1, R,kl,kr,zl,zr,val); ElseChange (p<<1, L,mid,kl,mid,zl,zr,val), Change (p<<1|1, mid+1, r,mid+1, Kr,zl,zr,val); } intQueryintPintLintRintKlintkrintZlintZR) { if(L = = KL && r = = KR)returnMx[p].query (1,1, M,ZL,ZR); intCur = tag[p].query (1,1, M,ZL,ZR), Mid = (l+r) >>1; if(KR <= mid) cur = max (Cur,query (p<<1, L,MID,KL,KR,ZL,ZR)); Else if(KL > Mid) cur = max (Cur,query (p<<1|1, mid+1, R,KL,KR,ZL,ZR)); Elsecur = max (Cur,max (Query (p<<1, L,MID,KL,MID,ZL,ZR), query (p<<1|1, mid+1, r,mid+1, KR,ZL,ZR))); returnCur//each time in the modification of the time to compare with the tag, the full coverage of the time, because it has been updated}}t;intMain () {n= Read (), M = Read (), k =read (); while(k--) {D= Read (), s = Read (), h = Read (), x = Read (), y =read (); intg = T.query (1,1, n,x+1, x+d,y+1, y+s);//Query Maximum ValueT.change (1,1, n,x+1, x+d,y+1, y+s,g+h);//Interval Modification} printf ("%d\n", T.query (1,1N1N1, M)); return 0;}
[POI2006] Tet-tetris 3D