【CF】310 Div.1 C. Case of Chocolate

线段树的简单题目,做一个离散化,O(lgn)可以找到id。RE了一晚上,额,后来找到了原因。

  1 /* 555C */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 #include <iterator>
 20 #include <iomanip>
 21 using namespace std;
 22 //#pragma comment(linker,"/STACK:102400000,1024000")
 23
 24 #define sti                set<int>
 25 #define stpii            set<pair<int, int> >
 26 #define mpii            map<int,int>
 27 #define vi                vector<int>
 28 #define pii                pair<int,int>
 29 #define vpii            vector<pair<int,int> >
 30 #define rep(i, a, n)     for (int i=a;i<n;++i)
 31 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 32 #define clr                clear
 33 #define pb                 push_back
 34 #define mp                 make_pair
 35 #define fir                first
 36 #define sec                second
 37 #define all(x)             (x).begin(),(x).end()
 38 #define SZ(x)             ((int)(x).size())
 39 #define lson            l, mid, rt<<1
 40 #define rson            mid+1, r, rt<<1|1
 41
 42 typedef struct {
 43     int x, y;
 44     char op[4];
 45 } node_t;
 46
 47 const int maxn = 2e5+5;
 48 const int maxm = 4e5+5;
 49 node_t Q[maxn];
 50 int rn[maxm];
 51 int mxr[maxm<<2];
 52 int mxc[maxm<<2];
 53 int rL[maxm<<2];
 54 int cT[maxm<<2];
 55 int L, R;
 56
 57 void build(int l, int r, int rt) {
 58     rL[rt] = 1;
 59     cT[rt] = 1;
 60     if (l == r)
 61         return ;
 62
 63     int mid = (l+r)>>1;
 64     build(lson);
 65     build(rson);
 66 }
 67
 68 inline void PushDownR(int rt) {
 69     int lb = rt<<1;
 70     int rb = lb | 1;
 71
 72     if (mxr[rt]) {
 73         rL[rt] = max(rL[rt], mxr[rt]);
 74         mxr[lb] = max(mxr[lb], mxr[rt]);
 75         mxr[rb] = max(mxr[rb], mxr[rt]);
 76         mxr[rt] = 0;
 77     }
 78 }
 79
 80 inline void PushDownC(int rt) {
 81     int lb = rt<<1;
 82     int rb = lb | 1;
 83
 84     if (mxc[rt]) {
 85         cT[rt] = max(cT[rt], mxc[rt]);
 86         mxc[lb] = max(mxc[lb], mxc[rt]);
 87         mxc[rb] = max(mxc[rb], mxc[rt]);
 88         mxc[rt] = 0;
 89     }
 90 }
 91
 92 inline void PushDown(int rt) {
 93     int lb = rt<<1;
 94     int rb = lb | 1;
 95
 96     if (mxr[rt]) {
 97         rL[rt] = max(rL[rt], mxr[rt]);
 98         mxr[lb] = max(mxr[lb], mxr[rt]);
 99         mxr[rb] = max(mxr[rb], mxr[rt]);
100         mxr[rt] = 0;
101     }
102
103     if (mxc[rt]) {
104         cT[rt] = max(cT[rt], mxc[rt]);
105         mxc[lb] = max(mxc[lb], mxc[rt]);
106         mxc[rb] = max(mxc[rb], mxc[rt]);
107         mxc[rt] = 0;
108     }
109 }
110
111 void updateR(int delta, int l, int r, int rt) {
112     if (L<=l && R>=r) {
113         mxr[rt] = max(mxr[rt], delta);
114         return ;
115     }
116
117     int mid = (l+r)>>1;
118
119     PushDownR(rt);
120     if (mid >= R) {
121         updateR(delta, lson);
122     } else if (mid < L) {
123         updateR(delta, rson);
124     } else {
125         updateR(delta, lson);
126         updateR(delta, rson);
127     }
128 }
129
130 void updateC(int delta, int l, int r, int rt) {
131     if (L<=l && R>=r) {
132         mxc[rt] = max(mxc[rt], delta);
133         return ;
134     }
135
136     int mid = (l+r)>>1;
137
138     PushDownC(rt);
139     if (mid >= R) {
140         updateC(delta, lson);
141     } else if (mid < L) {
142         updateC(delta, rson);
143     } else {
144         updateC(delta, lson);
145         updateC(delta, rson);
146     }
147 }
148
149 pii query(int l, int r, int rt) {
150     if (l == r) {
151         rL[rt] = max(rL[rt], mxr[rt]);
152         cT[rt] = max(cT[rt], mxc[rt]);
153         mxr[rt] = 0;
154         mxc[rt] = 0;
155
156         pii p(rL[rt], cT[rt]);
157         return p;
158     }
159     int mid = (l+r)>>1;
160
161     PushDown(rt);
162     if (mid >= R) {
163         return query(lson);
164     } else {
165         return query(rson);
166     }
167 }
168
169 int main() {
170     ios::sync_with_stdio(false);
171     #ifndef ONLINE_JUDGE
172         freopen("data.in", "r", stdin);
173         freopen("data.out", "w", stdout);
174     #endif
175
176     int n, q;
177     mpii tb;
178     sti st;
179
180     scanf("%d %d", &n, &q);
181     rep(i, 0, q) {
182         scanf("%d %d %s", &Q[i].y, &Q[i].x, Q[i].op);
183         st.insert(Q[i].x);
184         st.insert(Q[i].y);
185     }
186     st.insert(1);
187
188     int m = 0;
189     int i, j, k;
190
191     for (sti::iterator siter=st.begin(); siter!=st.end(); ++siter) {
192         k = *siter;
193         ++m;
194         rn[m] = k;
195         tb[k] = m;
196     }
197
198     int x, y, idx, idy;
199     int ans;
200     pii p;
201
202     build(1, m, 1);
203     rep(i, 0, q) {
204         x = Q[i].x;
205         y = Q[i].y;
206         if (Q[i].op[0] == ‘U‘) {
207             idy = tb[y];
208             L = R = idy;
209             p = query(1, m, 1);
210             updateC(x+1, 1, m, 1);
211             ans = x - p.sec + 1;
212             idx = tb[x];
213             k = lower_bound(rn+1, rn+1+m, p.sec) - rn;
214             L = k;
215             R = idx;
216             if (L <= R)
217                 updateR(y+1, 1, m, 1);
218         } else {
219             idx = tb[x];
220             L = R = idx;
221             p = query(1, m, 1);
222             updateR(y+1, 1, m, 1);
223             ans = y - p.fir + 1;
224             idy = tb[y];
225             k = lower_bound(rn+1, rn+1+m, p.fir) - rn;
226             L = k;
227             R = idy;
228             if (L <= R)
229                 updateC(x+1, 1, m, 1);
230         }
231         #ifndef ONLINE_JUDGE
232         printf("L = %d, R = %d\n", L, R);
233         #endif
234         if (ans < 0)
235             ans = 0;
236         printf("%d\n", ans);
237     }
238
239     #ifndef ONLINE_JUDGE
240         printf("time = %d.\n", (int)clock());
241     #endif
242
243     return 0;
244 }
时间: 2024-10-18 20:15:49

【CF】310 Div.1 C. Case of Chocolate的相关文章

【CF】121 Div.1 C. Fools and Roads

题意是给定一棵树.同时,给定如下k个查询: 给出任意两点u,v,对u到v的路径所经过的边进行加计数. k个查询后,分别输出各边的计数之和. 思路利用LCA,对cnt[u]++, cnt[v]++,并对cnt[LCA(u, v)] -= 2.然后dfs求解各边的计数. 1 /* 191C */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #inc

【CF】207 Div.1 B.Xenia and Hamming

这题目一看很牛逼,其实非常easy.求求最小公倍数,最大公约数,均摊复杂度其实就是O(n). 1 /* 356B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <dequ

【CF】196 Div.2 Book of Evil

显然这个图是一课树,看着题目首先联想到LCA(肯定是可以解的).但是看了一下数据大小,应该会TLE.然后,忽然想到一个前面做过的题目,大概是在一定条件下树中某结点旋转成为根后查询最长路径.结果灵感就来了,主要思路是对于每个结点,第一次dfs得到两个变量到P结点的最大值以及次大值.然后,第二次dfs对于当前结点u,u到它的子树中P类结点的最大距离已知(nd[u].mx),那么除u的其他结点v到P类结点的最大距离加上v到u的距离和的最大值为pmx,可以通过每次深搜计算出来,只要d大于等于两者的最大值

【CF】110 Div.1 B. Suspects

这题目乍眼一看还以为是2-sat.其实很水的,O(n)就解了.枚举每个人,假设其作为凶手.观察是否满足条件.然后再对满足的数目分类讨论,进行求解. 1 /* 156B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vec

【CF】174 Div.1 B Cow Program

思路是树形DP+状态压缩.其实仅有2个状态,奇数次来到x或者偶数次来到x.(因为对x的更新不同).同时开辟visit数组,解决环.注意,一旦遇到环结果就是-1.DP数组存放第奇数/偶数次来到x时,对y的改变两. 1 /* 283B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include

【CF】259 Div.1 B Little Pony and Harmony Chest

还蛮有趣的一道状态DP的题目. 1 /* 435B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm

【CF】142 Div.1 B. Planes

SPFA.注意状态转移条件,ans的求解需要在bfs中间求解.因为只要到了地点n,则无需等待其他tourist.还是蛮简单的,注意细节. 1 /* 229B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector&g

Codeforces Round #310 (Div. 1) C. Case of Chocolate (线段树)

题目地址:传送门 这题虽然是DIV1的C..但是挺简单的..只要用线段树分别维护一下横着和竖着的值就可以了,先离散化再维护.每次查找最大的最小值<=tmp的点,可以直接在线段树里搜,也可以二分去找. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.

Codeforces Round #310 (Div. 1) C Case of Chocolate

思路:对于每个点而言.只与它相邻的两个点有关系.所以可以用stl或者线段树来找到它的相邻点. 代码:187ms(开挂之后貌似是最快的- -) #include <cstdio> #include <map> #include <algorithm> using namespace std; const int N = 200000 + 1; int x[N], y[N], t[N]; //适用于正负整数 template <class T> inline b