luogu P1503 鬼子进村

Posted mrclr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1503 鬼子进村相关的知识,希望对你有一定的参考价值。

嘟嘟嘟

 

线段树好题。

其实挺水的,想暴力怎么做:每一次从这个点开始向两边扩,直到遇到第一个摧毁的房屋。

那么把暴力改成倍增,然后线段树查询区间和是否为0。时间复杂度O(nlog2n)。

题解好像有线段树的O(nlogn)的做法,但是特别麻烦,也没怎么看懂。

技术分享图片
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(‘ ‘)
 14 #define Mem(a, x) memset(a, x, sizeof(a))
 15 #define rg register
 16 typedef long long ll;
 17 typedef double db;
 18 const int INF = 0x3f3f3f3f;
 19 const db eps = 1e-8;
 20 const int maxn = 5e4 + 5;
 21 inline ll read()
 22 {
 23   ll ans = 0;
 24   char ch = getchar(), last =  ;
 25   while(!isdigit(ch)) {last = ch; ch = getchar();}
 26   while(isdigit(ch)) {ans = ans * 10 + ch - 0; ch = getchar();}
 27   if(last == -) ans = -ans;
 28   return ans;
 29 }
 30 inline void write(ll x)
 31 {
 32   if(x < 0) x = -x, putchar(-);
 33   if(x >= 10) write(x / 10);
 34   putchar(x % 10 + 0);
 35 }
 36 
 37 int n, m;
 38 char c[2];
 39 
 40 int l[maxn << 2], r[maxn << 2], sum[maxn << 2];
 41 void build(int L, int R, int now)
 42 {
 43   l[now] = L; r[now] = R;
 44   if(L == R) return;
 45   int mid = (L + R) >> 1;
 46   build(L, mid, now << 1);
 47   build(mid + 1, R, now << 1 | 1);
 48 }
 49 void update(int now, int id, int flg)
 50 {
 51   if(l[now] == r[now]) {sum[now] += flg; return;}
 52   int mid = (l[now] + r[now]) >> 1;
 53   if(id <= mid) update(now << 1, id, flg);
 54   else update(now << 1 | 1, id, flg);
 55   sum[now] = sum[now << 1] + sum[now << 1 | 1];
 56 }
 57 int query(int L, int R, int now)
 58 {
 59   if(l[now] == L && r[now] == R) return sum[now];
 60   int mid = (l[now] + r[now]) >> 1;
 61   if(R <= mid) return query(L, R, now << 1);
 62   else if(L > mid) return query(L, R, now << 1 | 1);
 63   else return query(L, mid, now << 1) + query(mid + 1, R, now << 1 | 1);
 64 }
 65 
 66 int solve(int x)
 67 {
 68   if(query(x, x, 1)) return 0;
 69   int ret = 0;
 70   for(int t = x, i = 20; i >= 0; --i)
 71     {
 72       int j = t + (1 << i) - 1;
 73       if(j > n) continue;
 74       if(!query(t, j, 1)) ret += (1 << i), t += (1 << i);
 75     }
 76   for(int t = x, i = 20; i >= 0; --i)
 77     {
 78       int j = t - (1 << i) + 1;
 79       if(j < 1) continue;
 80       if(!query(j, t, 1)) ret += (1 << i), t -= (1 << i);
 81     }
 82   return ret - 1;
 83 }
 84 
 85 int st[maxn], top = 0;
 86 
 87 int main()
 88 {
 89   n = read(); m = read();
 90   build(1, n, 1);
 91   for(int i = 1; i <= m; ++i)
 92     {
 93       scanf("%s", c);
 94       if(c[0] == D)
 95     {
 96       st[++top] = read();
 97       update(1, st[top], 1);
 98     }
 99       else if(c[0] == R) update(1, st[top--], -1);
100       else
101     {
102       int x = read();
103       write(solve(x)), enter;
104     }
105     }
106   return 0;
107 }
View Code

 

以上是关于luogu P1503 鬼子进村的主要内容,如果未能解决你的问题,请参考以下文章

题解Luogu P1503 鬼子进村

洛谷—— P1503 鬼子进村

洛谷 P1503 鬼子进村

P1503 鬼子进村

luogu1503

[洛谷1053] 鬼子进村