• 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
  • 相关阅读:
    Django-admin管理工具
    docker-ce安装与搭建私有仓库
    docker-建立私有registry
    UBUNTU 下设置全局 path变量
    REDIS学习(1)环境搭建
    mongodb学习(1) 第一次开启 mongdb
    linux 添加 $path
    php cgi 与 cli 区别
    mysql 分区信息查看
    php 编译安装选项
  • 原文地址:https://www.cnblogs.com/mrclr/p/9841121.html
Copyright © 2020-2023  润新知