一.位运算
二、相关例题
1.知识点:set可以自动实现去重和排
#include<iostream>
#include<set>
using namespace std;
set<int> s;
int main() {
set<int>::iterator it;
int n,x;
cin>>n;
s.clear();
while(n--){
cin>>x;
s.insert(x);
}
cout<<s.size()<<endl;
for(it=s.begin();it!=s.end();it++){
cout<<*it<<' ';
}
cout<<endl;
return 0;
}
2.map
MAP映射:
map就是映射,也可以说是键值对
map<typea,typeb> m;从typea到typeb的映射,
储存在变量m里用起来就像数组一样,m[typea]=typeb;
不允许相同的typea,因为将键只能找到一个值,后面的定义会覆盖前面的定义;
支持查找,插入,删除,清空等操作,以及一些高端操作:如迭代器遍历,详情可参考http://cplusplus.com/reference/map/map/clear/
例题:计蒜客 T1875(保龄球)
#include<iostream>
#include<map>
using namespace std;
map<int,int> m;
map<int,int>::iterator it;//迭代器
int main(){
int n,q;
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
m[x]=i;
}
cin>>q;
while(q--){
int y;
cin>>y;
it=m.find(y);
if(it!=m.end()) cout<<it->second<<endl;
else cout<<"0"<<endl;
}
return 0;
}
3.单调队列
单调队列是一种主要用于解决滑动窗口类问题的数据结构,即,在长度为n的序列中,求每个长度为m的区间的区间最值
计蒜客 - T1897 (计算区间内的最小值)
#include<iostream>
#include<deque>
using namespace std;
int v[2000006];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<n;++i)
cin>>v[i];
deque<int> q;//存储序号
cout<<'0'<<endl;//第一位数字前无数字,所以是零
for(int i=1;i<n;i++){
if(!q.empty()&&i-q.front()>=m) q.pop_front();//过期的数字移出队列
while(!q.empty()&&v[q.back()]>v[i]) q.pop_back();//栈要找最小值,所以前面大的数要弹出去
q.push_back(i);//新的小数字如队列
printf("%d\n",v[q.front()]);
}
return 0;
}
4.单调栈
例题:POJ - 3250 ( D - Bad Hair Day)
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
const long long MAX=1e9+1;
long long allSum(vector<int> &v){//最大高度达1e9超出了int范围
v.push_back(MAX);//需要一个无限高的牛挡住栈中的牛,否则,最后一个元素无法出栈
stack<int> s;
long long sum=0;
for(int i=0;i<(int)v.size();i++){
if(s.empty()||v[s.top()]>v[i]) s.push(i);
else{
while(!s.empty()&&v[s.top()]<=v[i]){
int top=s.top();
s.pop();
sum+=(i-top-1);
}
s.push(i);
}
}
return sum;
}
int main(){
vector<int> v;
int n;
cin>>n;
for(int i=0;i<n;i++){
int x;
cin>>x;
v.push_back(x);
}
cout<<allSum(v);
return 0;
}