2 条题解
-
2
我认为题解并没有学到STL的精髓......
1:初始思路
看到题目,我们可以知道其实这个地道就是一条链,中间断了两边就无法相通
那题目让我们输出每一个被围堵的士兵能够到达的房子有几个,就是我们要从小到大维护被摧毁的房子编号,每两个编号间的差再就是答案,因为边界不能走
这时,我们能想到的两个特殊性质之一:自动排序,刚好满足我们的维护需求
2:完成题目
第个任务的输出答案已经出来了,就是在 时找到在中比大的第一个和比小的最后一个,位置之差即为答案
最后只剩完成前面的任务了
第个任务也迎刃而解,只需即可
那就只差第个任务了,它让我们将上一个加入的数掉,这时难道想不到用后进先出的性质吗?!
吐槽:题解还非要开一个数组来从尾到头地记录,直接,需要时取出的不就行了嘛,由此可见题解的并不能熟练运用.....
然后实现即可AC
#include<bits/stdc++.h> using namespace std; set<int>s;stack<int>id; int main() { int n,m;scanf("%d%d",&n,&m); s.insert(0);s.insert(n+1); while(m--) { char op[2];scanf("%s",op); if(op[0]=='D') { int x;scanf("%d",&x); s.insert(x);id.push(x); } else if(op[0]=='R') { if(s.size()) { int x=id.top(); id.pop();s.erase(x); } } else { int x;scanf("%d",&x); if(s.find(x)!=s.end())puts("0"); else { auto it=s.lower_bound(x); printf("%d\n",*it-*(--it)-1); } } } return 0; } -
0
这题用线段树,平衡树都能过
但是其实我们可以用STL中的set
设一个set记录当前被炸的房子编号,并且维护编号从小到大,当我们查询x时,找到在s中比x大的第一个和比x小的最后一个,位置之差减1即为答案。
代码出奇的短
#include<bits/stdc++.h> #define M 50010 using namespace std; int q[M],tail,n,m; set<int> s; set<int>:: iterator it; int main() { scanf("%d%d",&n,&m); s.insert(0); s.insert(n+1); for(int i=1;i<=m;i++) { char c; cin>>c;//用scanf会把空格读进来 if(c=='D') { int x; // 加入x scanf("%d",&x); s.insert(x); q[++tail]=x; } if(c=='Q') { int x; //查询 scanf("%d",&x); it=s.lower_bound(x); if(*it==x) { printf("0\n"); continue; } int ans=*it-*(--it); printf("%d\n",ans-1); } if(c=='R') //删除 { it=s.find(q[tail--]); s.erase(it); } } return 0; }
- 1
信息
- ID
- 1835
- 时间
- 500ms
- 内存
- 160MiB
- 难度
- 8
- 标签
- 递交数
- 19
- 已通过
- 5
- 上传者