开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情
位运算:
0)一个整数的负数是原数的补码 (也就是取反加1) 所以 ~x+1 =-x
1)求n的第k位数字 :n >> k & 1
2)lowbit(x) 函数: 作用:返回x的最后一位1代表的值 实现:x&(-x) 也可以写成: x&(~x+1)
例子:输入n个数,求每个数的二进制序列中1的个数
#include<iostream>
using namespace std;
int lowbit(int x)
{
return x&(-x);//x&(~x+1);
}
int main()
{
int n = 0;
cin >> n;
while(n--)
{
int x ;
cin >> x;
int res = 0;
while(x)
{
x-=lowbit(x); //每次减去x的最后一位1代表的值,相当于把那一位1去掉
res++;
}
cout << res <<" ";
}
return 0;
}
离散化
如何实现去重 -> 使用
unique函数
vector<int> alls; // 存储所有待离散化的值
sort(alls.begin(), alls.end()); // 将所有值排序
alls.erase(unique(alls.begin(), alls.end()), alls.end());// 去掉重复元素
注意:必须先排序,然后再使用unique函数
区间合并
简单来说:就是把有交集的区间进行合并,端点相交也合并
例子:区间合并:www.acwing.com/problem/con…
第一步:按照区间左端点排序,第二步:维护当前的区间[start,end],假设当前扫描到第i个区间,有下面三种情况:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int start,end;
vector<pair<int,int>> a;
for(int i = 0 ; i < n ;++i)
{
cin >> start >> end;
a.push_back({start,end});
}
//以左端点排升序
sort(a.begin(),a.end()); //pair排序优先以第一个成员排序,然后以第二个成员排序
//维护[start,end]区间
start = a[0].first,end = a[0].second;
int count = 1;
for(int i = 1 ; i < n ;++i)
{
if(end >= a[i].second) //情况1 (当前扫描的区间在当前维护的区间内)
{
continue;
}
else if(end >= a[i].first) //情况2 :end <= a[i].second && end >= a[i].first
{
end = a[i].second; //两个区间有交集,扩大当前维护的区间的尾
}
else //情况3:区间已经没有交集,更改维护的区间
{
start= a[i].first;
end = a[i].second;
++count;//之前的区间合并成一个
}
}
cout << count <<endl;
return 0;
}
写法2:将情况1和情况2合并, 直接取右端点的max作为答案
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void merge(vector<pair<int,int>>& segs) //将所有存在交集的区间合并
{
vector<pair<int,int>> res;//存储区间合并之后的结果
//pair排序优先以第一个成员排序,然后以第二个成员排序
sort(segs.begin(),segs.end());
//维护当前区间,最初没有遍历任何区间,设置一个边界值:负无穷到正无穷
//因为范围是-10^9 ~10^9 所以范围取:[-2e9,-2e9]
int st = -2e9 , ed = -2e9;
for(auto& e : segs) //扫描所有的区间
{
if(ed < e.first) //case1:没有交集
{
if(st != -2e9)
res.push_back({st,ed}); //合并的区间放到res中
//更新维护的区间
st = e.first;
ed = e.second;
}
else //情况1,2合并 :有交集
{
//当前维护的区间和当前区间有交集 ,把右端点更新为更长的那个
ed = max(ed , e.second);
}
}
if(st != -2e9) //为了防止输入的数组里面是没有任何区间的
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;
}
int的最小值为−2147483648,所以取−2e9比较省事,可以代表int的最小值
还有一些可以代表int最小值的数,例如,-0x3f3f3f3f-,-(1<<30)