基础算法
排序
快速排序模板
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int q[N];
void quick_sort(int q[],int l,int r)
{
if(l>=r) return;
int i=l-1,j=r+1, x=q[l+r>>1];
while(i<j)
{
do i++; while(q[i]<x);
do j--; while(q[j]>x);
if(i<j) swap(q[i],q[j]);
}
quick_sort(q,l,j);
quick_sort(q,j+1,r);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&q[i]);
quick_sort(q,0,n-1);
for(int i=0;i<n;i++) printf("%d ",q[i]);
return 0;
}
归并排序模板
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
int q[N],temp[N];
void merge_sort(int q[], int l, int r)
{
if(l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid ), merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1, tmp[r - l + 1];
while(i <= mid && j <= r)
if(q[i] <= q[j]) tmp[k++] = q[i++];
else tmp[k++] = q[j++];
while(i <= mid) tmp[k++] = q[i++];
while(j <= r) tmp[k++] = q[j++];
for(k = 0, i = l; i <= r; k++, i++) q[i] = tmp[k];
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&q[i]);
merge_sort(q,0,n-1);
for(int j=0;j<n;j++) printf("%d ",q[j]);
return 0;
}
二分模板
#include<iostream>
using namespace std;
const int N=1e5+5;
int n,m,q[N];
int main()
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&q[i]);
while(m--)
{
int k;scanf("%d",&k);
int l=-1,r=n;
while(l+1!=r)
{
int mid=l+r>>1;
if(q[mid]>=k) r=mid;
else l=mid;
}
if(q[r]!=k) printf("-1 -1\n");
else{
printf("%d ",r);
int ll=-1,rr=n;
while(ll+1!=rr)
{
int mid=ll+rr>>1;
if(q[mid]<=k) ll=mid;
else rr=mid;
}
if(q[ll]!=k) printf("%d\n",r);
else printf("%d\n",ll);
}
}
}
https:
高精度
高精度加法模板
#include<bits/stdc++.h>
using namespace std;
vector<int> add(vector<int> &A,vector<int> &B)
{
vector<int> C;
int t=0;
for(int i=0;i<A.size()||i<B.size();i++)
{
if(i<A.size()) t+=A[i];
if(i<B.size()) t+=B[i];
C.push_back(t%10);
t/=10;
}
if(t) C.push_back(1);
return C;
}
int main()
{
string a,b;
cin>>a>>b;
vector<int>A,B;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');
auto C=add(A,B);
for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
return 0;
}
高精度减法模板
#include<bits/stdc++.h>
using namespace std;
bool cmp(vector<int>&A,vector<int> &B)
{
if(A.size()!=B.size()) return A.size()>B.size();
for(int i=A.size()-1;i>=0;i--)
if(A[i]!=B[i]) return A[i]>B[i];
return true;
}
vector<int> sub(vector<int>&A,vector<int>&B)
{
vector<int>C;
int t=0;
for(int i=0;i<A.size();i++)
{
if(i<A.size()) t=A[i]-t;
if(i<B.size()) t-=B[i];
C.push_back((t+10)%10);
if(t<0) t=1;
else t=0;
}
while(C.size()>1&&C.back()==0) C.pop_back();
return C;
}
int main()
{
string a,b;
vector<int> A,B;
cin>>a>>b;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');
vector<int>C;
if(cmp(A,B)) C=sub(A,B);
else C=sub(B,A),cout << '-';
for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
cout<<endl;
return 0;
}
高精度乘法模板
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> add(vector<int> A, vector<int> B) {
vector<int> C(max(A.size(), B.size()) + 7, 0);
for (int i = 0; i < A.size(); i ++) C[i] += A[i];
for (int i = 0; i < B.size(); i ++) C[i] += B[i];
for (int i = 0; i + 1 < C.size(); i ++) {
C[i + 1] += C[i] / 10;
C[i] %= 10;
}
while (C.size() > 1 && C.back() == 0) C.pop_back();
reverse(C.begin(), C.end());
return C;
}
vector<int> mul(vector<int> A, vector<int> B) {
vector<int> C(A.size() + B.size() + 7, 0);
for (int i = 0; i < A.size(); i ++) {
for (int j = 0; j < B.size(); j ++) {
C[i + j] += A[i] * B[j];
}
}
for (int i = 0; i + 1 < C.size(); i ++) {
C[i + 1] += C[i] / 10;
C[i] %= 10;
}
while (C.size() > 1 && C.back() == 0) C.pop_back();
reverse(C.begin(), C.end());
return C;
}
int main() {
string s1 = "9899", s2 = "100";
vector<int> A, B;
for (int i = s1.size() - 1; i >= 0; i --) A.push_back(s1[i] - '0');
for (int i = s2.size() - 1; i >= 0; i --) B.push_back(s2[i] - '0');
vector<int> C = add(A, B);
cout << s1 << "+" << s2 << "=";
for (int i = 0; i < C.size(); i ++) cout << C[i];
cout << endl;
C = mul(A, B);
cout << s1 << "*" << s2 << "=";
for (int i = 0; i < C.size(); i ++) cout << C[i];
cout << endl;
return 0;
}
链接:https:
高精度除法
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> div(vector<int> &A,int B,int &r){
vector<int> C;
for(int i=0;i<A.size();i++){
r=r*10+A[i];
C.push_back(r/B);
r=r%B;
}
reverse(C.begin(),C.end());
while(C.size()>1&&C.back()==0) C.pop_back();
return C;
}
int main(){
string a;
int B,r=0;
cin>>a>>B;
vector<int> A;
for(int i=0;i<a.size();i++) A.push_back(a[i]-'0');
auto C = div(A,B,r);
for(int i=C.size()-1;i>=0;i--) cout<<C[i];
cout<<endl<<r;
cout<<endl;
return 0;
}
前缀和与差分
前缀和
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+10;
int a[N],sum[N];
int main()
{
int n,m,x;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>x;
sum[i]=x+sum[i-1];
}
while(m--)
{
int l,r;
cin>>l>>r;
cout<<sum[r]-sum[l-1]<<endl;
}
return 0;
}
一维差分模板
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N],b[N];
void insert(int &l,int &r,int &c)
{
b[l]+=c;
b[r+1]-=c;
}
int main()
{
int n,m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
for (int i = 1; i <= n; i ++ ) insert(i,i,a[i]);
while(m--)
{
int l,r,c;
scanf("%d%d%d", &l, &r,&c);
insert(l,r,c);
}
for (int i = 1; i <=n; i ++ ) b[i]+=b[i-1];
for (int i = 1; i <=n; i ++ ) printf("%d ",b[i]);
return 0;
}
双指针算法
最长连续不重复子序列
# include <iostream>
using namespace std;
const int N = 100010;
int a[N], s[N];
int main()
{
int n, r = 0;
cin >> n;
for (int i = 0, j = 0; i < n; ++ i)
{
cin >> a[i];
++ s[a[i]];
while (s[a[i]] > 1) -- s[a[j++]];
r = max(r, i - j + 1) ;
}
cout << r;
return 0;
}
位运算
//这里主要是了解一个lowbit操作
#include<bits/stdc++.h>
using namespace std;
int lowbit(int &x)//这个代码的关键是这个函数,每次输出x=的最后一位1;
{
return x&-x;
}
int main()
{
int n;
cin>>n;
while (n -- )
{
int x;
cin >> x;
int res=0;
while(x>0) x-=lowbit(x),res++;//每次减去x的最后一位1;直到没有1,那么res即为所求
cout << res<<" ";
}
}
区间和
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 300010;
int n, m;
int a[N];
int s[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());
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);
int r = find(item.second);
printf("%d\n", s[r] - s[l-1]);
}
return 0;
}
区间合并
这里看到一个区间合并,很绝的思路模板
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
typedef pair<int,int> PII;
PII a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)scanf("%d%d",&a[i].first,&a[i].second);
sort(a+1,a+n+1);
int ed=a[1].second,ans=0;
for(int i=2;i<=n;i++)
{
if(ed>=a[i].first)ed=max(ed,a[i].second);
else ans++,ed=a[i].second;
}
cout<<ans+1<<endl;
}