快速排序:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
vector<int> ans;
int n;
void quick(int min,int max){
if(min>=max) return ;
int x=ans[min+max>>1],l=min-1,r=max+1;
while(l<r){
do l++;
while(ans[l]<x);
do r--;
while(ans[r]>x);
if(l<r) swap(ans[l],ans[r]);
}
quick(min,r);
quick(r+1,max);
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
int x; cin>>x;
ans.push_back(x);
}
quick(0,n-1);
for(auto t:ans)
cout<<t<<' ';
}
归并排序:【归并排序可以求逆序对,也可以求出只能交换相邻两个数时,最少需要交换多少次】
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
vector<int> ans;
int n;
int tmp[N];
void meger(int min,int max){
if(min>=max) return;
int mid=min+max>>1;
meger(min,mid); meger(mid+1,max);
int l=min,r=mid+1,fur=min;
while(l<=mid&&r<=max){
if(ans[l]<ans[r]) tmp[fur++]=ans[l++];
else tmp[fur++]=ans[r++];
}
while(l<=mid) tmp[fur++]=ans[l++];
while(r<=max) tmp[fur++]=ans[r++];
for(int i=min;i<=max;i++){
ans[i]=tmp[i];
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
int x; cin>>x;
ans.push_back(x);
}
meger(0,n-1);
for(auto t:ans) cout<<t<<' ';
}
二维前缀和:
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1010;
ll st[N][N];
int n,m,k;
void init(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
st[i][j]=st[i-1][j]+st[i][j-1]-st[i-1][j-1]+st[i][j];
}
}
}
ll query(int x1,int y1,int x2,int y2){
return st[x2][y2]-st[x1-1][y2]-st[x2][y1-1]+st[x1-1][y1-1];
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
cin>>st[i][j];
}
init();
while(k--){
int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2;
cout<<query(x1,y1,x2,y2)<<endl;
}
}
二维差分:
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1010;
ll st[N][N];
int n,m,k;
void insert(int x1,int y1,int x2,int y2,int c){
st[x1][y1]+=c;
st[x1][y2+1]-=c; st[x2+1][y1]-=c;
st[x2+1][y2+1]+=c;
}
void init(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
st[i][j]=st[i-1][j]+st[i][j-1]-st[i-1][j-1]+st[i][j];
}
}
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int x; cin>>x;
insert(i,j,i,j,x);
}
}
while(k--){
int x1,y1,x2,y2,w; cin>>x1>>y1>>x2>>y2>>w;
insert(x1,y1,x2,y2,w);
}
init();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
cout<<st[i][j]<<' ';
cout<<endl;
}
}
高精度除法:
#include<vector>
#include<algorithm>
#include<iostream>
#include<string>
#define ll long long
using namespace std;
string a;
vector<ll> ans;
ll b,r;
void div(vector<ll> &ans,ll b){
int t=0;
vector<ll> mid;
for(int i=0;i<ans.size();i++){
t=t*10+ans[i];
mid.push_back(t/b);
t%=b;
}
r=t;
reverse(mid.begin(),mid.end());
while(!mid.back()&&mid.size()>1) mid.pop_back();
reverse(mid.begin(),mid.end());
ans=mid;
}
int main(){
cin>>a>>b;
for(int i=0;i<a.size();i++) ans.push_back(a[i]-'0');
div(ans,b);
for(auto t:ans) cout<<t;
cout<<endl<<r;
}
高精度乘法:
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#define ll long long
using namespace std;
vector<ll> ans;
ll b;
string a;
void mul(vector<ll> &ans,ll b){
vector<ll> mid; ll t=0;
for(int i=0;i<ans.size()||t;i++){
if(i<ans.size()) t+=b*ans[i];
mid.push_back(t%10);
t/=10;
}
while(!mid.back()&&mid.size()>1) mid.pop_back();
ans=mid;
}
int main(){
cin>>a>>b;
for(int i=0;i<a.size();i++){
ans.push_back(a[i]-'0');
}
reverse(ans.begin(),ans.end());
mul(ans,b);
for(int i=ans.size()-1;i>=0;i--) cout<<ans[i];
}
辗转相除法【欧几里得法】:
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll a,b;
ll gcd(ll a,ll b){
return !(a%b)?b:gcd(b,a%b);
}
int main(){
cin>>a>>b;
cout<<gcd(a,b);
}
拓展欧几里得算法:
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll a,b;
ll exgcd(ll a,ll b,ll &x,ll &y){
ll d=a;
if(b){
d=exgcd(b,a%b,y,x);
y-=(a/b)*x;
}else{
x=1,y=0;
}
return d;
}
int main(){
cin>>a>>b;
ll x,y,m=exgcd(a,b,x,y);
printf("%lld*%lld+%lld*%lld=%lld",a,x,b,y,m);
}
快速幂:
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll a,b,mod;//a^b%mod
ll ans=1;
int main(){
cin>>a>>b>>mod;
for(int i=b;i;i>>=1){
if(i&1) ans*=a,ans%=mod;
a*=a; a%=mod;
}
cout<<ans;
}
素数筛【获得最小质因数】
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N=100010;
ll mi[N];
bool st[N];
ll n;
void get_prime(){
mi[1]=1;
for(int i=2;i<=n;i++){
if(!st[i]){
for(int j=i*2;j<=n;j+=i){
st[j]=1; mi[j]=i;
}
mi[i]=i;
}
}
}
int main(){
cin>>n;
get_prime();
for(int i=2;i<=n;i++)
if(!st[i]) cout<<i<<' ';
cout<<endl;
for(int i=2;i<=n;i++)
cout<<mi[i]<<' ';
}
获取因数:
#include<iostream>
#include<algorithm>
#include<vector>
#include<math.h>
#define ll long long
using namespace std;
ll a;
vector<ll> ans;
void get_num(int x){
for(int i=1;i<=sqrt(x);i++){
if(x%i==0){
ans.push_back(i);
ans.push_back(x/i);
}
}
}
int main(){
cin>>a;
get_num(a);
sort(ans.begin(),ans.end());
for(ll t:ans) cout<<t<<' ';
}
质因数分解【如果是对多个数分解,则要配合上面的素数筛】
#include<iostream>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
ll a;
vector<ll> ans;
int main(){
cin>>a;
for(int i=2;i<=a/i;i++){
while(!(a%i)){
ans.push_back(i);
a/=i;
}
}
if(a!=1) ans.push_back(a);
for(auto t:ans) cout<<t<<' ';
}
迪杰斯特拉【堆优化】:
#include<iostream>
#include <vector>
#include<algorithm>
#include<cstring>
#include<queue>
#define x first
#define y second
#define ll long long
using namespace std;
const int N=150010;
struct p{
ll ne,w;
};
typedef pair<ll,ll> two;
vector<vector<p>> g(N);
int n,m;
ll dist[N];
bool st[N];
ll dj(){
priority_queue<two,vector<two>,greater<two>> que;
memset(dist,0x3f,sizeof dist);
que.push({0,1});
dist[1]=0;
while(que.size()){
two t=que.top();
que.pop();
if(st[t.y]) continue;
st[t.y]=1;
for(int i=0;i<g[t.y].size();i++){
int id=g[t.y][i].ne,w=g[t.y][i].w;
if(dist[id]>dist[t.y]+w){
dist[id]=dist[t.y]+w;
que.push({dist[id],id});
}
}
}
return dist[n]>1e9?-1:dist[n];
}
int main(){
cin>>n>>m;
for(int i=0;i<m;i++){
ll a,b,w; cin>>a>>b>>w;
g[a].push_back({b,w});
}
cout<<dj();
}
弗洛伊德算法:
#include<iostream>
#include <vector>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int N=210;
ll w[N][N];
int n,m,k;
int main(){
memset(w,0x3f,sizeof w);
cin>>n>>m>>k;
for(int i=0;i<m;i++){
ll x,y,z; cin>>x>>y>>z;
w[x][y]=min(w[x][y],z);
}
for(int i=1;i<=n;i++) w[i][i]=0;
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
w[i][j]=min(w[i][j],w[i][k]+w[k][j]);
}
}
}
while(k--){
int a,b; cin>>a>>b;
if(w[a][b]>1e9) cout<<"impossible"<<endl;
else cout<<w[a][b]<<endl;
}
}
模拟堆:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int n,m,cnt;
int st[N];
void down(int x){
int t=x;
if(t*2<=cnt&&st[t*2]<st[x]) x=t*2;
if(t*2+1<=cnt&&st[t*2+1]<st[x]) x=t*2+1;
if(t!=x){
swap(st[x],st[t]);
down(x);
}
}
void up(int x){
for(int i=x;i>=1;i/2){
int fa=i/2;
if(st[fa]>st[i]) swap(st[fa],st[i]);
else break;
}
}
int main(){
cin>>n>>m; cnt=n;
for(int i=1;i<=n;i++) cin>>st[i];
for(int i=n/2;i>=1;i--) down(i);
for(int i=0;i<m;i++){
cout<<st[1]<<' ';
st[1]=st[cnt--];
down(1);
}
}