I. content
Winter vacation is coming, and it's time for Xiao Ming to date the goddesses. Although Xiao Ming is a loser, she is very active. The goddesses often reply "ha ha" after a lot of speeches on Xiao Ming's website. Therefore, Xiao Ming's favorite is dating the goddesses. At the same time, there are many friends looking for him to open a black shop. Because the number is too large, how to arrange the time has become a big concern for Xiao Ming. We know that Xiaoming has a total of T free time, during which there will be many goddesses or friends to find Xiaoming. As an operating system once scored 71 points, Xiao Ming thought of an algorithm, that is, "the first adaptive algorithm". According to the description of the operating system textbook, it is to find the most advanced continuous space to allocate to each request, so Xiao Ming made a decision: When a base friend comes to find Xiaoming, Xiaoming will find a free time to make an appointment with the base friend according to the "first adaptation algorithm". If it is found, it will say "X,let's fly" (here, X is the start time), otherwise it will say "fly with yourself"; When the goddess comes to find Xiaoming, she first uses the "first adaptation algorithm". If she doesn't find it, Xiaoming risks to ignore all the loser's agreements, and then uses "ignore the first adaptation algorithm". Once she finds it twice, she says "X,don't put my gezi" (here, X is the start time), otherwise she says "wait for me" Of course, we know that Xiaoming is not a man with infinite moral burden. If he has a date with the goddess and has time left, he will still go to dota with his original friends. (for example, Xiao Xi (diaosi) and Xiao Ming have an appointment to play dota in the period of 1-5. At this time, the goddess comes to make an appointment with Xiao Ming for a period of 3, so the final appointment is 1-3 Xiao Ming to date with the goddess, and then play dota with Xiao Xi in the period of 4-5 after the appointment.) Xiao Ming occasionally wants to learn new knowledge. At this time, Xiao Ming will empty all the scheduled time in a certain time interval to learn and roar "I am the hope of chinese chengxuyuan!!", but Xiao Ming is usually hot for three minutes. If someone makes a reservation, Xiao Ming will allocate the time to learn new knowledge according to his loneliness.
Input
Input the first line CASE, indicating that there is CASE group test data; Each group of data starts with two integers T, N, T represents the total time, n represents the number of appointment requests; Next N lines, each line represents an appointment of a goddess or a base friend, "NS QT" represents a goddess coming to find Xiao Ming for a period of time about QT, "DS QT" represents a loser's QT request, of course, Xiao Ming wants to learn knowledge, "study!! LR" represents all the requests within the L~R interval. [Technical Specification] 1. 1 <= CASE <= 30 2. 1 <= T, N <= 100000 3. 1 <= QT <= 110000 4. 1 <= L <= R <=T
Output
For each case, the first line outputs "Case C:" which represents the number of cases, and then N lines, each line corresponds to the result of a request (refer to the description). Output sample (copy here): "X,let's fly","fly with yourself","X,don't put my gezi","wait for me","I am the hope of chinese chengxuyuan!!"
Sample Input
1 5 6 DS 3 NS 2 NS 4 STUDY!! 1 5 DS 4 NS 2
Sample Output
Case 1: 1,let's fly 4,don't put my gezi wait for me I am the hope of chinese chengxuyuan!! 1,let's fly 1,don't put my gezi
Two, train of thought
- Two line trees are used to maintain the time period reserved by boys and girls respectively. In the line segment tree, the maximum continuous sub segment sum is saved. The idle time is 1. If it is reserved, it is 0.
- When the boy comes to make an appointment, just modify the line tree of the boy. When a girl comes to make an appointment, if she can't find free time in the boy's line tree, she can find it in the girl's line tree. If she finds it, she can modify the two line trees of the boy and the girl (because the girl can ignore her friends).
- Each time the query is modified, the interval is lowered.
- The query can be divided into three situations. First, if the query function is called, there must be so much free time.
1. In the left section
2. The answer obtained by combining the left and right intervals. In this case, you can directly return to the left end of this interval.
3. In the right section
Three, code
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int N = 1e5 + 5; struct Node { int lmax, rmax, ans;// lmax represents the maximum continuous interval from the left endpoint and rmax represents the sum of the maximum continuous interval from the right endpoint to the left //ans is the largest continuous interval sum } b[N << 2], g[N << 2]; int t, n, m, x, y; char s[10]; void pushup(int id, int l, int r) { //St > = 0 update B st > = 1 update g int mid = (l + r) >> 1; Node &root = b[id], < = b[id << 1], &rt = b[id << 1 | 1]; root.lmax = lt.lmax + (lt.lmax == (mid - l + 1) ? rt.lmax : 0); //If the maximum sum on the left is the whole interval, then add the lmax of the right interval root.rmax = rt.rmax + (rt.rmax == (r - mid) ? lt.rmax : 0); root.ans = max(max(lt.ans, rt.ans), lt.rmax + rt.lmax); Node &groot = g[id], &glt = g[id << 1], &grt = g[id << 1 | 1]; groot.lmax = glt.lmax + (glt.lmax == (mid - l + 1) ? grt.lmax : 0); groot.rmax = grt.rmax + (grt.rmax == (r - mid) ? glt.rmax : 0); groot.ans = max(max(glt.ans, grt.ans), glt.rmax + grt.lmax); } void pushdown(int id, int l, int r) { //b g arrays are all lowered int mid = (l + r) >> 1; Node &root = b[id], < = b[id << 1], &rt = b[id << 1 | 1]; if (root.ans == r - l + 1) { //Explain the decentralization caused by learning lt.lmax = lt.rmax = lt.ans = mid - l + 1; rt.lmax = rt.rmax = rt.ans = r - mid; } if (root.ans == 0) { //Delegation due to appointment lt.lmax = lt.rmax = lt.ans = 0; rt.lmax = rt.rmax = rt.ans = 0; } //Reference can only be assigned once Node &groot = g[id], &glt = g[id << 1], &grt = g[id << 1 | 1]; if (groot.ans == r - l + 1) { //Explain the decentralization caused by learning glt.lmax = glt.rmax = glt.ans = mid - l + 1; grt.lmax = grt.rmax = grt.ans = r - mid; } if (groot.ans == 0) { //Delegation due to appointment glt.lmax = glt.rmax = glt.ans = 0; grt.lmax = grt.rmax = grt.ans = 0; } } void build(int id, int l, int r) { if (l == r) { b[id].ans = b[id].lmax = b[id].rmax = g[id].ans = g[id].lmax = g[id].rmax = 1; return ; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); pushup(id, l, r); } void update(int id, int l, int r, int x, int y, int st) { if (x <= l && r <= y) { if (st == 0) { //For boys change to 0 b[id].lmax = b[id].rmax = b[id].ans = 0; } else { //Change both boys and girls to 0 st = = 2 means both boys and girls to 1 b[id].lmax = b[id].rmax = b[id].ans = (st == 1 ? 0 : r - l + 1); g[id].lmax = g[id].rmax = g[id].ans = (st == 1 ? 0 : r - l + 1); } return ; } pushdown(id, l, r); int mid = (l + r) >> 1; if (x <= mid) update(id << 1, l, mid, x, y, st); if (y > mid) update(id << 1 | 1, mid + 1, r, x, y, st); pushup(id, l, r); } int query(int id, int l, int r, int x, int st) { if (l == r) return l; //When a single point is found, it can only be returned. Because we have judged before querying, it means that the result must be found before querying pushdown(id, l, r); int mid = (l + r) >> 1; //In three cases, it is either in the left interval. If it is not in the left interval, then judge whether it is the combination of the left interval and the right interval. If it is not, it can only be in the right interval if (st == 0) { //Query b line tree Node &root = b[id], < = b[id << 1], &rt = b[id << 1 | 1]; if (lt.ans >= x) { return query(id << 1, l, mid, x, st); } else if ((lt.rmax + rt.lmax) >= x) { return mid - lt.rmax + 1; } else { return query(id << 1 | 1, mid + 1, r, x, st); } } if (st == 1) { Node &groot = g[id], &glt = g[id << 1], &grt = g[id << 1 | 1]; if (glt.ans >= x) { return query(id << 1, l, mid, x, st); } else if ((glt.rmax + grt.lmax) >= x) { return mid - glt.rmax + 1; } else { return query(id << 1 | 1, mid + 1, r, x, st); } } } int main() { scanf("%d", &t); for (int ci = 1; ci <= t; ci++) { scanf("%d%d", &n, &m); build(1, 1, n); printf("Case %d:\n", ci); for (int i = 1; i <= m; i++) { scanf("%s%d", s, &x); if (s[0] == 'D') { if (b[1].ans >= x) { int t = query(1, 1, n, x, 0); update(1, 1, n, t, t + x - 1, 0); printf("%d,let's fly\n", t); } else { printf("fly with yourself\n"); } } else if (s[0] == 'N') { if (b[1].ans >= x) { int t = query(1, 1, n, x, 0); // 0 means to query in b array update(1, 1, n, t, t + x - 1, 1); //1 means that the interval of b and g arrays is updated to 0 2 means that the interval is updated to 1 printf("%d,don't put my gezi\n", t); } else if (g[1].ans >= x) { int t = query(1, 1, n, x, 1); update(1, 1, n, t, t + x - 1, 1); printf("%d,don't put my gezi\n", t); } else { printf("wait for me\n"); } } else { scanf("%d", &y); update(1, 1, n, x, y, 2); printf("I am the hope of chinese chengxuyuan!!\n"); } } } return 0; }