zoukankan      html  css  js  c++  java
• # luogu P1503 鬼子进村

嘟嘟嘟

线段树好题。

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

那么把暴力改成倍增，然后线段树查询区间和是否为０。时间复杂度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;
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 {
90   build(1, n, 1);
91   for(int i = 1; i <= m; ++i)
92     {
93       scanf("%s", c);
94       if(c[0] == 'D')
95     {
97       update(1, st[top], 1);
98     }
99       else if(c[0] == 'R') update(1, st[top--], -1);
100       else
101     {
103       write(solve(x)), enter;
104     }
105     }
106   return 0;
107 }```
View Code
• 相关阅读:
MySQL事务的介绍+事务的特性+事务的开启
MySQL误操作删除后，怎么恢复数据？
笔记本如何开启WiFi热点?
zabbix: Get value from agent failed: cannot connect to [[172.16.179.10]:10050]: [4] Interrupted system call
考取RHCE认证的历程，总结的经验
find的-xdev参数解释？
keepalived+mysql主从环境，keepalived返回值是RST，需求解决方法？
Centos 7 LVM xfs文件系统修复
本文讲述下windows下使用rsync备份数据
MySQL索引介绍+索引的存储类型+索引的优点和缺点+索引的分类+删除索引
• 原文地址：https://www.cnblogs.com/mrclr/p/9841121.html