快速排序
快速排序
#include
#include
using namespace std;
int n;
int s[100000];
int main()
{
cin>>n;
for(int i=0;i>s[i];
}
sort(s,s+n);
for(int i=0;i
第K个数
#include
#include
using namespace std;
int a[100005];
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
nth_element(a+1,a+k,a+1+n);
cout<
归并排序
归并排序
#include
using namespace std;
const int N = 100010;
int n;
int q[N],tmp[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=1,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(int i=l,j=1;i<=r;i++,j++)
{
q[i]=tmp[j];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&q[i]);
}
merge_sort(q,1,n);
for(int i=1;i<=n;i++)
{
printf("%d ",q[i]);
}
return 0;
}
逆序对的数量
#include
using namespace std;
typedef long long ll;
const int N = 100010;
int n;
int q[N],tmp[N];
ll merge_sort(int l,int r)
{
if(l>=r)
{
return 0;
}
int mid = (l+r)>>1;
ll res=merge_sort(l,mid)+merge_sort(mid+1,r);
//归并的过程
int k=1,i=l,j=mid+1;
while(i<=mid&&j<=r)
{
if(q[i]<=q[j])
{
tmp[k++]=q[i++];
}
else
{
tmp[k++]=q[j++];
res+=(mid-i+1);
}
}
//扫尾
while(i<=mid)
{
tmp[k++]=q[i++];
}
while(j<=r)
{
tmp[k++]=q[j++];
}
//物归原主
for(int i=l,j=1;i<=r;i++,j++)
{
q[i]=tmp[j];
}
return res;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>q[i];
}
cout<
二分
数的范围
#include
using namespace std;
const int N = 100010;
int q[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i>q[i];
}
while(m--)
{
int x;
cin>>x;
int l=0,r=n-1;
while(l>1;
if(q[mid]>=x)
{
r=mid;
}
else l=mid+1;
}
if(q[l]!=x)
{
cout<<"-1 -1"<>1;
if(q[mid]<=x)
{
l=mid;
}
else r=mid-1;
}
cout<
数的三次方根
#include
using namespace std;
int main()
{
double n;
cin>>n;
double l=-10000,r=10000;
while(r-l>1e-8)
{
double mid = (l+r)/2;
if(mid*mid*mid>=n)
{
r=mid;
}
else l=mid;
}
printf("%.6lf\n",l);
return 0;
}
高精度
高精度加法
Python一行就可以解决
print(int(input())+int(input()))
#include
#include
#include
using namespace std;
vector add(vector &A,vector &B)
{
vectorC;
int t=0;
for(int i=0;i>a>>b;
vectorA,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--)
{
cout<
高精度减法
#include
#include
#include
using namespace std;
//判断是否有A>=B
bool cmp(vector &A,vector &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;
}
//C=A-B
vector sub(vector &A,vector &B)
{
vectorC;
int t=0;
for(int i=0;i1&&C.back()==0)
{
C.pop_back();
}
return C;
}
int main()
{
string a,b;
cin>>a>>b;
vectorA,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');
}
if(cmp(A,B))
{
auto C = sub(A,B);
for(int i=C.size()-1;i>=0;i--)
{
cout<=0;i--)
{
cout<
高精度乘法
#include
#include
using namespace std;
vector mul(vector& A, int b)
{
vectorC;
int t = 0;
for (int i = 0; i < A.size() || t; i++)
{
if (i < A.size())
{
t += A[i] * b;
}
C.push_back(t % 10);
t /= 10;
}
while(C.size()>1&&C.back()==0)
{
C.pop_back();
}
return C;
}
int main()
{
string a;
int b;
cin >> a >> b;
vectorA;
for (int i = a.size() - 1; i >= 0; i--)
{
A.push_back(a[i] - '0');
}
auto C = mul(A, b);
for (int i = C.size() - 1; i >= 0; i--)
{
cout << C[i];
}
return 0;
}
高精度除法
#include
#include
#include
using namespace std;
vector div(vector& A, int b,int &r)
{
vectorC;
r=0;
for (int i = A.size()-1; i >= 0; i--)
{
r = r * 10 + A[i];
C.push_back(r/b);
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;
cin >> a >> b;
vectorA;
for (int i = a.size() - 1; i >= 0; i--)
{
A.push_back(a[i] - '0');
}
int r;
auto C = div(A, b,r);
for (int i = C.size() - 1; i >= 0; i--)
{
cout << C[i];
}
cout<
前缀和与差分
前缀和
#include
using namespace std;
const int N = 100005;
int a[N],s[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
s[i]=s[i-1]+a[i];
}
while(m--)
{
int l,r;
cin>>l>>r;
cout<
子矩阵的和
#include
using namespace std;
const int N = 1010;
int a[N][N], s[N][N];
int main()
{
int n, m, q;
cin >> n >> m >> q;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
scanf("%d", &a[i][j]);
s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + a[i][j]; // 求前缀和
}
while (q--)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
// 算子矩阵的和
printf("%d\n", s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]);
}
return 0;
}
差分
#include
using namespace std;
const int N = 100010;
int n,m;
int a[N],b[N];
void insert(int l,int r,int c)
{
b[l]+=c;
b[r+1]-=c;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
insert(i,i,a[i]);
}
while(m--)
{
int l,r,c;
cin>>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++)
{
cout<
差分矩阵
#include
using namespace std;
const int N = 1010;
int n,m,q;
int a[N][N],b[N][N];
void insert(int x1,int y1,int x2,int y2,int c)
{
b[x1][y1]+=c;
b[x2+1][y1]-=c;
b[x1][y2+1]-=c;
b[x2+1][y2+1]+=c;
}
int main()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
insert(i,j,i,j,a[i][j]);
}
}
while(q--)
{
int x1,y1,x2,y2,c;
cin>>x1>>y1>>x2>>y2>>c;
insert(x1,y1,x2,y2,c);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<
双指针算法
最长连续不重复子序列
#include
using namespace std;
const int N = 100010;
int n;
int a[N],s[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int res=0;
for(int i=1,j=1;i<=n;i++)
{
s[a[i]]++;
while(s[a[i]]>1)
{
s[a[j]]--;
j++;
}
res=max(res,i-j+1);
}
cout<
数组元素的目标和
#include
using namespace std;
const int N = 100005;
int n,m,x;
int a[N],b[N];
int main()
{
cin>>n>>m>>x;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=m;i++)
{
cin>>b[i];
}
for(int i=1,j=m;i<=n;i++)
{
while(j>=1&&a[i]+b[j]>x) j--;
if(a[i]+b[j]==x)
{
cout<
判断子序列
#include
using namespace std;
const int N = 100005;
int n,m;
int a[N],b[N];
int main()
{
cin>>n>>m;
for(int i=0;i>a[i];
}
for(int i=0;i>b[i];
}
int i=0,j=0;
while(i
位运算
二进制中1的个数
#include
using namespace std;
int lowbit(int x)
{
return x & -x;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int x;
cin>>x;
int res=0;
while(x)
{
x-=lowbit(x);
res++;
}
cout<
离散化
区间和
#include
#include
#include
using namespace std;
const int N = 300010; //n次插入和m次查询相关数据量的上界
int n, m;
int a[N];//存储坐标插入的值
int s[N];//存储数组a的前缀和
vector alls; //存储(所有与插入和查询有关的)坐标
vector> 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;
}
区间和并
区间和并
#include
#include
#include
using namespace std;
typedef pairpii;
const int N = 100010;
int n;
vectorsegs;
void merge(vector&segs)
{
vectorres;
sort(segs.begin(),segs.end());
int st=-2e9,ed=-2e9;
for(auto seg:segs)
{
if(ed>n;
for(int i=0;i>l>>r;
segs.push_back({l,r});
}
merge(segs);
return 0;
}