版权声明:小蒟蒻的博客转载也请注明出处哦 https://blog.csdn.net/qq_42835823/article/details/83892173
基础算法
归并排序(逆序对)
树状数组:
for(int i=n;i>0;i--){
ans+=query(a[i]-1);
add(a[i],1);
}
归并排序:
void guibing(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
guibing(l,mid);guibing(mid+1,r);
int i=l,j=mid+1;
for(int k=l;k<=r;k++)
if(j>r||(i<=mid&&a[i]<=a[j]))b[k]=a[i++];
else b[k]=a[j++],ans+=mid-i+1;
for(int k=l;k<=r;k++)a[k]=b[k];
}
离散化
#include<bits/stdc++.h>
using namespace std;
int n,m,peo[200005],mov1[200005],mov2[200005],a[600005],b[600005],ans=1,joy[200005],sat[200005];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&peo[i]);
a[i]=peo[i];
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d",&mov1[i]);
a[i+n]=mov1[i];
}
for(int i=1;i<=m;i++){
scanf("%d",&mov2[i]);
a[i+n+m]=mov2[i];
}
sort(a+1,a+n+m+m+1);
int r=unique(a+1,a+n+m+m+1)-a-1;
for(int i=1,h;i<=n;i++){
h=lower_bound(a+1,a+r+1,peo[i])-a;
b[h]++;
}
for(int i=1;i<=m;i++){
joy[i]=lower_bound(a+1,a+r+1,mov1[i])-a;
sat[i]=lower_bound(a+1,a+r+1,mov2[i])-a;
if(b[joy[i]]>b[joy[ans]])ans=i;
else if(b[joy[i]]==b[joy[ans]]&&b[sat[i]]>b[sat[ans]])ans=i;
}
printf("%d",ans);
return 0;
}
字符串
KMP
int lena=strlen(a+1),lenb=strlen(b+1),ans=0;
for(int i=2,j=0;i<=lenb;i++){
while(j>0&&b[i]!=b[j+1])j=nxt[j];
if(b[i]==b[j+1])j++;
nxt[i]=j;
}
for(int i=1,j=0;i<=lena;i++){
while(j>0&&a[i]!=b[j+1])j=nxt[j];
if(a[i]==b[j+1])j++;
if(j==lenb){
ans++;
j=0;
}
}
trie树
#include<bits/stdc++.h>
using namespace std;
int n,c[100000][55],tot=0,val[100000],ans=0;
char s[60];
void insert(){
int len=strlen(s+1),p=0,e=0;
for(int i=1;i<=len;i++){
int r=s[i]-'a';
if(!c[p][r]){
tot++;
c[p][r]=tot;
memset(c[tot],0,sizeof(c[tot]));//
}
p=c[p][r];
e+=val[p];
}
val[p]=1;
ans=max(ans,e+1);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
insert();
}
printf("%d",ans);
return 0;
}
HASH
太难了,不管了,用unordered_map就好了……
数据结构
并查集
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}//fa[x]=find(fa[x]);路径压缩,节约时间
inline void merge(int x,int y){
if(find(x)!=find(y))fa[find(x)]=find(y);
}
树状数组
int t[N<<2];
inline void add(int x,int v){
for(;x<=n;x+=x&-x)t[x]+=v;
}
inline int query(int x){
int ret=0;
for(;x;x-=x&-x)ret+=t[x];
return t[x];
}
ST表
#include<bits/stdc++.h>
using namespace std;
int n,mx[100010][20],m,lg[100010];
void prework(){
lg[1]=0;
for(int i=2;i<=n;i++)
lg[i]=lg[i>>1]+1;
for(int k=1;(1<<k)<=n;k++)
for(int i=1;i+(1<<k-1)<=n;i++)
mx[i][k]=max(mx[i][k-1],mx[i+(1<<(k-1))][k-1]);
}
int query(int x,int y){
int c=lg[y-x+1];
return max(mx[x][c],mx[y-(1<<c)+1][c]);//
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&mx[i][0]);
prework();
while(m--){
int u,v;
scanf("%d%d",&u,&v);
printf("%d\n",query(u,v));
}
return 0;
}
线段树
#include<bits/stdc++.h>
using namespace std;
#define lc (p<<1)
#define rc (p<<1|1)
int n,m;
struct Tree{
int l,r,lazy,sum;
}t[400010];
void built(int p,int l,int r){
t[p].l=l;t[p].r=r;t[p].sum=t[p].lazy=0;
if(l==r)return;
int mid=l+r>>1;
built(lc,l,mid);
built(rc,mid+1,r);
}
void pushdown(int p){
if(!t[p].lazy)return;
t[lc].lazy+=t[p].lazy;
t[rc].lazy+=t[p].lazy;
t[lc].sum+=(t[lc].r-t[lc].l+1)*t[p].lazy;
t[rc].sum+=(t[rc].r-t[rc].l+1)*t[p].lazy;
t[p].lazy=0;
}
void add(int p,int l,int r){//val默认为1
if(l<=t[p].l&&t[p].r<=r){
t[p].sum+=(t[p].r-t[p].l+1);
t[p].lazy++;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(mid>=l)add(lc,l,r);
if(mid<r)add(rc,l,r);
t[p].sum=t[rc].sum+t[lc].sum;
}
int query(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r)return t[p].sum;
pushdown(p);
int mid=t[p].l+t[p].r>>1,ans=0;
if(mid>=l)ans+=query(lc,l,r);
if(mid<r)ans+=query(rc,l,r);
return ans;
}
int main(){
cin>>n>>m;
built(1,1,n);
while(m--){
int x,y;char c;
cin>>c;
if(c=='T'){
cin>>x>>y;
add(1,x,y);
}
else{
cin>>x;
if(query(1,x,x)%2==0)printf("yes\n");
else printf("no\n");
}
}
return 0;
}
图论
最短路
dijkstra
void dijkstra(){
priority_queue< pair<int,int> >q;
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
q.push(make_pair(0,1));
while(!q.empty()){
int u=q.top().second;q.pop();
if(vis[u])continue;
vis[u]=1;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
q.push(make_pair(-dis[v],v));
}
}
}
}
SPFA
还没复习到呢~~
Floyed
注意其实只有两个块不连通。
最后新加边后,直径可能还是比原来小。
#include<bits/stdc++.h>
using namespace std;
struct point{
int a,b;
}a[155];
int n;
double e[155][155],dis[155][155]={0},mxdis[155]={0},mx=0;
char s[155];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].a,&a[i].b);
for(int i=1;i<=n;i++){
double r;
scanf("%s",s+1);
for(int j=1;j<=n;j++){
r=sqrt((a[i].a-a[j].a)*(a[i].a-a[j].a)+(a[i].b-a[j].b)*(a[i].b-a[j].b));
dis[i][j]=(s[j]=='1'?r:1e20);
e[i][j]=r;
}
}
for(int k=1;k<=n;k++)//////////////////////////////////////////////
for(int i=1;i<=n;i++){
dis[i][i]=0;
for(int j=1;j<=n;j++)
dis[i][j]=(dis[i][k]+dis[k][j]<dis[i][j])?dis[i][k]+dis[k][j]:dis[i][j];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
if(dis[i][j]!=1e20)mxdis[i]=max(mxdis[i],dis[i][j]);
mx=max(mx,mxdis[i]);
}
double ans=1000000000.00;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dis[i][j]==1e20)ans=min(ans,mxdis[i]+mxdis[j]+e[i][j]);
}
}
printf("%.6lf",max(ans,mx));
return 0;
}
#include<bits/stdc++.h>
using namespace std;
char s[35];
int b[12][12];
int k,g=0;
long long ans=1;
int main(){
scanf("%s",s+1);
scanf("%d",&k);
for(int i=1,l,r;i<=k;i++){
scanf("%d%d",&l,&r);
b[l][r]=1;
}
for(int k=0;k<=9;k++)
for(int i=0;i<=9;i++){
b[i][i]=1;
for(int j=0;j<=9;j++)
b[i][j]|=b[i][k]&b[k][j];
}
for(int i=1;i<=strlen(s+1);i++){
int r=0,e=s[i]-'0';
if(e==0)r=1;
for(int j=1;j<=9;j++)if(b[e][j])r++;
ans*=r;
while(ans%10==0){
g++;
ans/=10;
}
}
printf("%lld",ans);
for(int i=1;i<=g;i++)printf("0");
return 0;
}
或:
bitset<12>b[12];
for(int i=0;i<=9;i++){
b[i][i]=1;
for(int j=0;j<=9;j++)
if(b[j].test(i))b[j]|=b[i];
}
次短路
还没复习到呢~~
K 短路
还没复习到呢~~
最小生成树
还没复习到呢~~
次小生成树
还没复习到呢~~
拓扑排序
还没复习到呢~~
Tarjan
还没复习到呢~~
差分约束
还没复习到呢~~
欧拉回路
还没复习到呢~~
LCA
还没复习到呢~~
树的直径
还没复习到呢~~
树上差分
还没复习到呢~~
数论
还没复习到呢~~
动态规划
还没复习到呢~~
搜索
还没复习到呢~~