快速排序
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);
}
归并排序
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;
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(i=l,j=0;i<=r;i++,j++)q[i]=tmp[j];
}
整数二分算法
bool check(int x){}
int bsearch_1(int l,int r){
while(l<r){
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
return l;
}
int bsearch_2(int l,int r){
while(l<r){
int mid=l+r+1>>1;
if(check(mid))l=mid;
else r=mid-1;
}
return l;
}
浮点数二分
bool check(double x){}
double bsearch_3(double l,double r){
double eps=1e-6;
while(r-l>eps){
double mid=(l+r)/2;
if(check(mid))r=mid;
else l=mid;
}
return l;
}
高精度加法
#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 100010
char a[N];
char b[N];
int A[N];
int B[N];
int main(){
scanf("%s %s",a,b);
int lenA=strlen(a);
int lenB=strlen(b);
int j=0;
int i=0;
for(i=lenA-1,j=0;i>=0;i--,j++)A[j]=a[i]-'0';
for(i=lenB-1,j=0;i>=0;i--,j++)B[j]=b[i]-'0';
int C[N];
int t=0;
for(i=0;i<lenA||i<lenB;i++){
if(i<lenA)t += A[i];
if(i<lenB)t += B[i];
C[i]=t%10;
t/=10;
}
if(t!=0){
C[i]=t;
for(j=i;j>=0;j--)printf("%d",C[j]);
}
for(j=i-1;j>=0;j--)printf("%d",C[j]);
return 0;
}
一维前缀和
S[i]=a[1]+a[2]+...+a[i];
a[l]+...+a[r]=S[r]-S[l-1];
二维前缀和
S[i,j]=第i行第j列格子左上部分所有元素的和
以(x1,y1)为左上角,(x2,y2)为右下角的子矩阵的和为:
S[x2,y2]-S[x1-1,y2]-S[x2,y1-1]+s[x1-1,y1-1]
一维差分
给区间[l,r]中的每个数加上c:B[l]+=c,B[r+1]-=c;
二维差分
给以(x1,y1)为左上角,(x2,y2)为右下角的子矩阵中的所有元素加上c:
S[x1,y1]+=c,S[x2+1,y1]-=c,S[x1,y2+1]-=c,S[x2+1,y2+1]+=c
位运算
求n的第k位数字:n>>k&1
返回n的最后一位1:lowbit(n)=n&-n
双指针算法
for(int i=0,j=0;i<n;i++){
while(j<i&&check(i,j))j++;
}
常见问题分类:
(1)对于一个序列,用两个指针维护一段区间
(2)对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
区间合并
#include<stdio.h>
#define N 100010
int n;
struct interval{
int l;
int r;
};
struct interval in[N];
struct interval res[N];
void quick_sort(int l,int r){
if(l>=r)return;
int i=l-1,j=r+1,x=in[(l+r)/2].l;
while(i<j){
do i++;while(in[i].l<x);
do j--;while(in[j].l>x);
if(i<j){
struct interval temp=in[i];
in[i]=in[j];
in[j]=temp;
}
}
quick_sort(l,j),quick_sort(j+1,r);
}
void merge(){
quick_sort(0,n-1);
int st=-2e9,ed=-2e9;
int i;
int k=1;
for(i=0;i<n;i++){
if(ed<in[i].l){
if(st!=-2e9){
res[k].l=st;
res[k++].r=ed;
}
st=in[i].l,ed=in[i].r;
}
else{
if(ed<in[i].r)ed=in[i].r;
}
}
printf("%d",k);
}
int main(){
scanf("%d",&n);
int i;
for(i=0;i<n;i++){
scanf("%d%d",&in[i].l,&in[i].r);
}
merge();
}