一、知识点:位运算
1.二进制中1的个数
给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 11 的个数。
输入格式
第一行包含整数 n
第二行包含 n个整数,表示整个数列。
输出格式
共一行,包含 n 个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中 1的个数。
输入样例:
5
1 2 3 4 5
输出样例:
1 1 2 1 2
//二进制中1的个数
//位运算
#include<iostream>
using namespace std;
int n;
const int N=100010;
int a[N];
int lowbit(int x){
return x&(-x);
}
int main(){
cin>>n;
while(n--){
int x;
cin>>x;
int res=0;
while(x){
x-=lowbit(x);
res++;
}
cout<<res<<' ';
}
return 0;
}
2.区间和
代码
//离散化 区间和
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n,m;
const int N=300010;
int s[N];
int a[N];
vector<int> alls;
vector<pair<int,int>> add,query;
int find(int x){
int l=0,r=alls.size()-1;
while(l<r){
int mid=l+r>>1;
if(alls[mid]>=x) r=mid;
else l=mid+1;
}
return r+1;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int x,c;
scanf("%d%d",&x,&c);
add.push_back({x,c});
alls.push_back(x);
}
for(int i=1;i<=m;i++){
int l,r;
scanf("%d%d",&l,&r);
query.push_back({l,r});
alls.push_back(l);
alls.push_back(r);
}
//排序,去重
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(),alls.end()),alls.end());
//执行前n次插入操作
for(auto item:add){
int x=find(item.first);
a[x]+=item.second;
}
//前缀和
for(int i=1;i<=alls.size();i++) s[i]=s[i-1]+a[i];
//m次
for(auto item:query){
int l=find(item.first);
int r=find(item.second);
printf("%d\n",s[r]-s[l-1]);
}
return 0;
}
3.区间合并
//区间合并
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef pair <int,int> PII;
const int N=100010;
vector<PII> segs;
int n;
void merge(vector<PII> &segs){
vector<PII> res;
sort(segs.begin(),segs.end());
int st=-2e9,ed=-2e9;
for(auto seg:segs){
if(ed<seg.first){
if(st!=-2e9) res.push_back({st,ed});
st=seg.first;
ed=seg.second;
}
else{
ed=max(ed,seg.second);
}
}
if(st!=-2e9) res.push_back({st,ed});
segs=res;
}
int main(){
scanf("%d",&n);
while(n--){
int l,r;
scanf("%d%d",&l,&r);
segs.push_back({l,r});
}
merge(segs);
cout<<segs.size()<<endl;
return 0;
}