1.位运算
(1)常见问题
- ①求n的第k位数字 :n >> k & 1
- ②返回n的最后一位1 : lowbit( n ) = n & (-n)
(2)题目示例1 : 二进制中1的个数
#include<iostream>
#include<vector>
using namespace std;
//解法1
int main()
{
int n;
cin >> n;
vector<int> a(n,0);
for(int i = 0 ; i < n ;++i) cin >> a[i];
for(int i = 0 ; i < n ;++i)
{
int temp = a[i];
int count = 0;
while(temp)
{
if(temp & 1)
{
count++;
}
temp = temp >> 1;
}
cout << count << " ";
}
return 0;
}
//解法2 : lowbit
#include<iostream>
using namespace std;
int lowbit(int x)
{
return x & -x;
}
int main()
{
int n;
cin >> n;
int temp = 0 ;
for(int i = 0 ; i < n ;++i)
{
cin >> temp;
int count = 0;
while(temp)
{
temp -= lowbit(temp);
++count;
}
cout << count << " ";
}
return 0;
}
2.离散化
(1)题目示例1 : 区间和
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> alls; //存所有可能的下标
vector<pair<int,int>> add; //存输入的所有添加数据
vector<pair<int,int>> query; //存输入所有的查询
//找到alls数组中x值对应的下标
int find(int x)
{
int l = 0;
int r = alls.size()-1;
while(l < r)
{
int mid = l + r >> 1;
if(alls[mid] >= x) r = mid;
else l = mid+1;
}
return l;
}
/*
//双指针去重
vector<int>::iterator unique(vector<int>& a)
{
int j = 0;
for(int i = 0 ; i < a.size() ;++i)
{
if(!i || a[i] != a[i-1])
{
a[j++] = a[i];
}
}
return a.begin()+j;
}
*/
int main()
{
int n, m;
cin >> n >> m;
int x,c; //x是下标, c是要增加的值
for(int i = 0 ; i < n ;++i)
{
cin >> x >> c;
add.push_back({x,c});
alls.push_back(x);
}
int l,r;
for(int i = 0 ; i < m ;++i)
{
cin >> l >> r;
query.push_back({l,r});
//要查询的下标可能没有数值,要添加到alls中,后面要能够查找到下标
alls.push_back(l);
alls.push_back(r);
}
//排序+去重
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(),alls.end()) , alls.end());
vector<int> a(alls.size(),0);//alls[i] 对应的下标中存 数据
//添加数据
for(auto& e : add)
{
int x = find(e.first);
a[x] += e.second;
}
//利用前缀和
for(int i = 1; i < a.size(); ++i)
{
a[i] += a[i-1];
}
//计算区间值
for(auto& e : query)
{
//找到区间对应的下标
int l = find(e.first);
int r = find(e.second);
cout << a[r] - a[l-1] << endl;
}
return 0;
}
3.区间合并
//写法1
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int l,r;
vector<pair<int,int>> a;
for(int i = 0 ; i < n ;++i)
{
cin >> l >> r;
a.push_back({l,r});
}
//按照left,升序排列
sort(a.begin(),a.end()); //优先比较 first
l = a[0].first;
r = a[0].second;
int count = 1;
for(int i = 1 ; i < n ;++i)
{
if(r >= a[i].second) //情况1
{
continue;
}
else if(r >= a[i].first) //情况2
{
r = a[i].second;
}
else //情况3
{
l = a[i].first;
r = a[i].second;
++count;
}
}
cout << count <<endl;
return 0;
}
//写法2
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void merge(vector<pair<int,int>>& segs)
{
vector<pair<int,int>> res;
sort(segs.begin(),segs.end()); //优先以first排序
int st = -2e9 , ed = -2e9; //边界 正无穷和负无穷
for(auto& e : segs)
{
if(ed < e.first)
{
if(st != -2e9) res.push_back({st,ed});
st = e.first;
ed = e.second;
}
else //情况1,2合并
{
ed = max(ed , e.second);
}
}
if(st != -2e9) //防止segs是空的
res.push_back({st,ed});
segs = res;
}
int main()
{
int n;
cin >> n;
int l,r;
vector<pair<int,int>> a;
for(int i = 0 ; i < n ;++i)
{
cin >> l >> r;
a.push_back({l,r});
}
merge(a);
cout << a.size() <<endl;
return 0;
}