Luogu P3960 Queue (Dynamic open point segment tree)

Source: Internet
Author: User
Tags ord

P3960 Parade

Test Instructions Topic Description

Sylviais a love of learning girls.

A while ago, Sylvia participated in the school military training. As we all know, military training needs to stand square.

SylviaIn the square in which there are \ (n \times m\) students, the number of rows of the Phalanx is \ (n\)and the number of columns is \ (m\).

In order to facilitate management, the instructor at the beginning of the training, according to the former, from left to right in order to the students in the matrix from \ (1\) to \ (n \times m\) numbered (see the following example). That is: At the beginning, the number of the student in column \ ( i\) line ( j\) is \ ((i-1) \times m + j\).

However, in the practice of the square, there are often students because of a variety of things need to leave. During the day, a total of \ (q\) Such a departure event occurred. Each departure event can be described by the number of pairs \ ((x, y) (1 \le x \le N, 1 \le y \le m) \) , which indicates that the student who is the first ( x\ ) row (y\ ) column is dropped out.

There was a vacancy in the team after the students had dropped out. For the team to be neat, the instructors will order such two instructions in turn:

Align to the left. At this point the first column remained motionless and all the students left to fill the vacancy. It is not difficult to find out that after this instruction, the vacancy is in section \ (x\) ( m\) column.

Forward. At this point the first line remained motionless, and all the students filled the vacancies forward. It is not difficult to find out that after this instruction, the vacancy is in section \ (n\) ( m\) column.

The instructor stipulated that two or more students could not leave at the same time. That is, the next student will be able to leave after the former student has returned. Therefore, in each of the students leaving the team to return, there is only n\ ( m\) row of a vacancy, then the students naturally fill this position.

Because the station square is really boring, so Sylvia want to calculate each time out of the event, the departure of the classmate number is.

Note: Each student's number will not be changed with the occurrence of the departure event, the number of students in the matrix after the departure event may be disorderly sequence.

Input output Format input format:

Enter a common \ (q+1\) line.

The \ ( 1\) line contains \ (3\) a space-delimited positive integer \ (n,m,q\), which indicates that the square size is \ (n\) the row \ (m\) column, altogether occurred \ ( q\) Minor event.

The next \ (q\) line describes the \ (q\) event in the order in which the event occurred. Each line is two integers \ (x,y\), separated by a space, which indicates that the student who dropped out of the departure event was in column x\ ( y\) .

Output format:

In the order in which events are entered, each event outputs an integer that represents the number of the dropped students in the outgoing event.

Input and Output Sample input example:
2 2 31 12 21 2
Sample output:
114
Description

"Input and Output sample description"

The process of queuing as shown, each line describes an event. In the first event, a classmate numbered \ (1\) is dropped out, and the vacancy is in the first column of the first row. Then all the students to the left, then the number of students (2\) to move one step to the left, the vacancy moved to the second column in the first row. Then all the classmates up, then the number of students (4\) up one step, then the vacancy moved to the second row in the second column. The last student numbered \ (1\) returned to fill the vacancy.

"Data size and conventions"

Data guarantees each event satisfies \ (1 \le x \le n,1 \le y \le m\)

Ideas

WWX, what are you doing? --diggersun
Lined up. --logeadd
...
How do wwx queue up? --uranus
You can open a tree in each row (splay\), and then use dynamic open points to optimize the space ... Hey, you don't go! --logeadd

As Konjac Konjac I do not have any high-level data structure, so I can only use a simple line tree to do this problem.

However, there are limitations in this space, which can only be used for dynamic open-point segment trees. This evening with this problem template, learning the dynamic open point, by the way also done this problem.

Go to the chase. Let's start by thinking about the meaning of the topic operation:

    1. The departure of a person, the equivalent of a single point of inquiry and delete.
    2. To the left, which is equivalent to the last column in the row, one less person in the last column.
    3. Forward to the line after the team to enter, equivalent to the last column to add a person.

Q: So what data structure supports single point of inquiry, single point of deletion, single point of adding it?

A:\ (splay\)(killed

A: Segment Tree and tree Array (positive solution!)

Based on the analysis of the operation, we open a segment tree in front \ ((m-1) \) of each line, and then open a single tree of line segments for the last column to complete all operations.

Specifically, we use the \ (sz\) array on each node of the segment tree to store the number of individuals under that node, deleting points when the direct violence removes points at the corresponding location, and \ ( update\) for each ancestor node \ (sz\) all minus one, the query according to \ (sz\) to jump around to find, add a point to the end of the line tree to add a dot.

Think again about the space problem. For the size of the segment tree, because there is a \ (q\) query, the worst case of all insert operation on the same line, so we each line segment tree size is \ ((m+q) \) , each column segment tree size is \ (((n+q) \) , The total space size is \ (((m+q) (n-1) + (n+q)), and only a \ (M \times n\) space We can not bear, the expected score is only \ (70\) , This is obviously not enough for the Logeadd giants who want AK , so we have to use a good operation: Dynamic open point.

Think of the meaning of the \ (lazytag\) label of the ordinary line-segment tree: If I query this node, then I am (pushdown\), because only in this case can the node and its son node be able to contribute to the answer, instead, If I don't query this node all the time, I'll just save the updated value instead of passing down, because at this point the value doesn't contribute to the answer. And the dynamic open point is the same, if we have not asked a period of time, we have been not to build that interval node. And once the query is made, we build the knot.

What is the actual operation? For example, we check a single point and delete it (you will find that in the above analysis the two operations are always linked together), so write:

ll GET_SZ (ll l,ll R)//First look at the following function {if (now==n+1)//Last column {if (r<=n) return r-l+1;//query at the beginning of the existence of the interval, because this paragraph has not been queried, so this paragraph    The Master is full if (l<=n) return n-l+1;//r has exceeded the interval, but L is still in the interval, and N is the end of the human being at the beginning, so the total is n-l+1 return 0;//is the new node, no one before any action }//the node if (r<m) return r-l+1;//that is established on the number of rows, the preceding if (l<m) return m-l;//is a part of the previous existence, the same as return 0;//all do not exist, Ibid.}ll ask (LL &id,ll l,ll r,ll x)//id is the current node number, L,r is the current interval, x is the position of the point to be queried in the segment tree, {if (!id)//The case has not opened this point {id=++cnt;//open point S Z[ID]=GET_SZ (l,r);//Gets the number of people in the interval of the current node management if (L==R)//To the last point, to record the person's number {if (now==n+1) val[id]=l*m;//the last column of the Number statistics Else val[id]= (now-1) *m+l;//number statistics for the first column}} sz[id]--;//this paragraph is less personal, direct-if (l==r) return val[id];// I found the man. LL mid= (l+r) >>1;//continue looking down Qwq if (!ls[id]&&x<= (mid-l+1)) | | SZ[LS[ID]]&GT;=X) return Ask (ls[id],l,mid,x)//In the left son can solve the problem else//to find the right son to solve the problem {if (!ls[id]) x-= (mid-l+1);//Statistical difference Less person can find else x-=sz[ls[id]];//ibid return ask(rs[id],mid+1,r,x);//Go to the right son}} 

Similarly, we handle the single-point join when this is handled:

void change(LL &id,LL l,LL r,LL x,LL v)//x还是表示插入位置,v为插入的权值{    if(!id)//建点    {        id=++cnt;//操作都是一样的        sz[id]=get_sz(l,r);        if(l==r) val[id]=v;//这里就不用特判是在最后一列还是别的了    }    sz[id]++;    if(l==r) return ;//改完了,溜了溜了    LL mid=(l+r)>>1;    if(x<=mid) change(ls[id],l,mid,x,v);//只要改左儿子    else change(rs[id],mid+1,r,x,v);//只要改右儿子}

The main code is here to end, in fact, the size is not very much? However, it is hoped that this year's data structure problem can be simple \ (qwq\).

Resentment--;
NOIP rp++;

AC Code
#include <bits/stdc++.h>using namespace Std;typedef long Long ll;const ll Maxn=3e5+5;const ll Maxm=1e7; LL N,m,q,p,now; LL CNT,RT[MAXN],ORD[MAXN],SZ[MAXM],LS[MAXM],RS[MAXM],VAL[MAXM];    ll read () {ll re=0;    Char Ch=getchar ();    while (!isdigit (CH)) Ch=getchar ();    while (IsDigit (CH)) re= (re<<3) + (re<<1) +ch-' 0 ', Ch=getchar (); return re;}        ll GET_SZ (ll L,ll R) {if (now==n+1) {if (r<=n) return r-l+1;        if (l<=n) return n-l+1;    return 0;    } if (r<m) return r-l+1;    if (l<m) return m-l; return 0;}        ll ask (ll &id,ll l,ll r,ll x) {if (!id) {id=++cnt;        SZ[ID]=GET_SZ (L,R);            if (l==r) {if (now==n+1) val[id]=l*m;        else val[id]= (now-1) *m+l;    }} sz[id]--;    if (l==r) return val[id];    LL mid= (l+r) >>1; if ((!ls[id]&&x<= (mid-l+1)) | |    SZ[LS[ID]]&GT;=X) return ask (LS[ID],L,MID,X);        else {if (!ls[id]) x-= (mid-l+1);        else X-=sz[ls[id]]; RetUrn Ask (rs[id],mid+1,r,x);        }}void Change (LL &id,ll l,ll r,ll x,ll v) {if (!id) {id=++cnt;        SZ[ID]=GET_SZ (L,R);    if (l==r) val[id]=v;    } sz[id]++;    if (l==r) return;    LL mid= (l+r) >>1;    if (x<=mid) change (LS[ID],L,MID,X,V); else change (rs[id],mid+1,r,x,v);}    int main () {N=read (), M=read (), Q=read ();    P=max (n,m) +q;        while (q--) {LL x=read (), Y=read (), Z;        if (y==m) now=n+1,z=ask (rt[now],1,p,x);        else Now=x,z=ask (rt[now],1,p,y);        printf ("%lld\n", z);        now=n+1;        Change (rt[now],1,p,n+ (++ord[now]), z);            if (y!=m) {z=ask (rt[now],1,p,x), now=x;        Change (rt[now],1,p,m-1+ (++ord[now]), z); }} return 0;}

Luogu P3960 Queue (Dynamic open point segment tree)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.