双指针
核心思想
利用朴素算法的单调性,将O(n^2)优化到O(n)。
算法模板
for(int i = 0, j = 0; i < n; i ++)
{
while(check(i, j))
{
...
j ++;
}
}
离散化(整数)
离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。
例如:
原数据:1,999,100000,15;处理后:1,3,4,2;
原数据:{100,200},{20,50000},{1,400};
处理后:{3,4},{2,6},{1,5};
例题
802.求区间和
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 1010;
typedef pair<int, int> PII;
int n, m;
int a[N], s[N];
vector<int> alls;
vector<PII> add, query;
int find(int x)
{
int l = 0, r = alls.size() -1;
while(l < r)
{
int mid = (l + r)/2;
if(alls[mid] >= x) r = mid;
else
l = mid + 1;
}
return r + 1;
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i ++)
{
int x, c;
cin >> x >> c;
add.push_back({x, c});
alls.push_back(x);
}
for(int i = 0; i < m; i ++)
{
int l, r;
cin >> 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());
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];
for(auto item : query)
{
int l = find(item.first), r = find(item.second);
cout << s[r] - s[l - 1] << endl;
}
return 0;
}
位运算
输出n二进制的第k位数字
公式:x >> k &1
#include<iostream>
using namespace std;
int main()
{
int n, k;
cin >> n >> k;
cout << (n >> k & 1) << endl;
}
求n二进制中1的个数
#include<iostream>
using namespace std;
int lowbit (int x)
{
return x & -x;
}
int main()
{
int x;
cin >> x;
int res = 0;
while(x) x -=lowbit(x), res ++;
cout << res << endl;
return 0;
}
区间合并
1.按区间左端点排序。
2.更新处理不同的情况(相离,相交)。
3.插入最后的区间。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef pair<int, int> PII;
int n;
vector<PII> add;
void merge(vector<PII> &add)
{
vector<PII> res;
int st = -2e9, ed = -2e9;
for(auto adds : add)
if(ed < adds.first)
{
if(st != -2e9) res.push_back({st, ed});
st = adds.first, ed = adds.second;
}
else
ed = max(ed, adds.second);
if(st != -2e9) res.push_back({st, ed});
add = res;//防止add输入为空
}
int main()
{
cin >> n;
for(int i = 0; i < n; i ++)
{
int l , r;
cin >> l >> r;
add.push_back({l, r});
}
sort(add.begin(), add.end());
merge(add);
cout << add.size() << endl;
}