Ubuntu執行*.sh檔案出現 bash: ./a.sh: /bin/bash^M: bad interpreter: No such file or directory問題解決方案
阿新 • • 發佈:2020-10-23
模板整理(持續整理中)
二分
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid-1;
}
並查集
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn=10005; int f[maxn]; int n,m; void init() { for(int i=1;i<=10000;i++) f[i]=i; } int get(int x) { return f[x]=(x==f[x]? x:get(f[x])); } void merge(int x,int y) { f[get(x)]=get(y); } int main() { }
快速冪
//位運算版本 #include <iostream> using namespace std; int power(int a,int b,int p) { int ans=1%p; for( ;b;b>>=1) { if(b&1) ans=(long long)ans*a%p; a=(long long)a*a%p; } return ans; } int main() { } //遞迴版本 #include <iostream> #include <cstdio> using namespace std; long long t,b,p,k,s,result=1; int pow(int a,int b,int p) { if(b==0) return 1; if(b==1) return a%p; t=pow(a,b/2,p); if(b>=2&&b%2==0) return t*t%p; if(b>=2&&b%2==1) return t*t*a%p; } int main() { }
線性篩素數
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn=10000005; int v[maxn],p[maxn];//v代表v是不是質數,是的話為1,p為質數 void primes(int n) { int m=0; memset(v,0,sizeof(v)); for(int i=2;i<=n;i++) { if(v[i]==0) { v[i]=i; p[++m]=i; } for(int j=1;j<=m;j++) { if(p[j]>v[i]||p[j]>(n/i)) break; v[i*p[j]]=p[j]; } } } int main() { }
鄰接表存樹,鄰接表存圖
const int N=100010,M=1000010;
int head[N],ver[M],edge[M],next[M],d[N],tot;
bool v[N];
void (int x,int y,int z)
{
ver[++tot]=y,edge[tot]=z,next[i]=head[x],head[x]=tot;
}
dfs
void dfs(int x){
v[x]=1;//記錄點x被訪問過,v是visit的縮寫
for(int i=head[x];i;i=next[i]){
int y=ver[i];
if(v[y]) continue;
dfs(y);
}
}
dfs序
void dfs(int x){
a[++m]=x;
v[x]=1;
for(int i=head[x];i;i=next[i]){
int y=ver[i];
if(v[y]) continue;
dfs(y);
}
a[++m]=x;
}
求樹的深度
void dfs(int x){
v[x]=1;
for(int i=head[x];i;i=next[i]){
int y=ver[i];
if(v[y]) continue;
d[y]=d[x]+1;
dfs(y);
}
}
樹的重心
void dfs(int x){
v[x]=1;size[i]=1;
int max_part=0;
for(int i=head[x];i;i=next[i]){
int y=ver[i];
if(v[y]) continue;
dfs(y);
size[x]+=size[y];
max_part=max(max_part,size[y]);
}
max_part=max(max_part,n-size[x]);
if(max_part<ans){
ans=max_part;
pos=x;
}
}
bfs
void bfs()
{
memset(d,0,sizeof(d));
queue<int> q;
q.push(1);d[1]=1;
while(q.size()>0){
int x=q.front();
q.pop;
for(int i=head[x];i;next[i]){
int y=ver[i];
if(d[y]) continue;
d[y]=d[x]+1;
q.push(y);
}
}
}
單源最短路徑
//spfa 慎用
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
const int N=100010,M=1000010;
int head[N],ver[M],edge[M],next[M],d[N];
bool v[N];
int n,m,s,tot;
queue <int> q;
void add(int x,int y,int z)
{
ver[++tot]=y,edge[tot]=z,next[tot]=head[x],head[x]=tot;
}
void spfa()
{
for(int i=1;i<=n;i++)
d[i]=2147483647;
memset(v,0,sizeof(v));
d[s]=0,v[s]=1;
q.push(s);
while(q.size())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=next[i])
{
int y=ver[i],z=edge[i];
if(d[y]>d[x]+z)
{
d[y]=d[x]+z;
if(!v[y]) q.push(y);
}
}
}
}
int main()
{
cin>>n>>m>>s;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
}
spfa();
for(int i=1;i<=n;i++)
cout<<d[i]<<" ";
return 0;
}
//dijkstra 常用
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
const int N=100010,M=1000010;
int head[N],ver[M],edge[M],next[M],d[N];
bool v[N];
int n,m,s,tot;
priority_queue <pair<int ,int> > q;
void add(int x,int y,int z)
{
ver[++tot]=y,edge[tot]=z,next[tot]=head[x],head[x]=tot;
}
void dijkstra()
{
for(int i=1;i<=n;i++)
d[i]=2147483647;
memset(v,0,sizeof(v));
d[s]=0;
q.push(make_pair(0,s));
while(q.size())
{
int x=q.top().second;
q.pop();
if(v[x]) continue;
v[x]=1;
for(int i=head[x];i;i=next[i])
{
int y=ver[i],z=edge[i];
if(d[y]>d[x]+z)
{
d[y]=d[x]+z;
q.push(make_pair(-d[y],y));
}
}
}
}
int main()
{
cin>>n>>m>>s;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
}
dijkstra();
for(int i=1;i<=n;i++)
cout<<d[i]<<" ";
return 0;
}
最小生成樹
//Prim
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#define re register
#define ll long long
using namespace std;
int a[5005][5005],n,m,ans,d[5005];
bool v[5005];
void prim()
{
memset(d,0x3f,sizeof(d));
memset(v,0,sizeof(v));
d[1]=0;
for(re int i=1;i<=n;i++)
{
int x=0;
for(re int j=1;j<=n;j++)
if(!v[j]&&(x==0||d[x]>d[j])) x=j;
v[x]=1;
for(re int y=1;y<=n;y++)
if(!v[y]) d[y]=min(d[y],a[x][y]);
}
}
int main()
{
cin>>n>>m;
memset(a,0x3f,sizeof(a));
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
a[y][x]=a[x][y]=min(a[x][y],z);
}
prim();
for(int i=2;i<=n;i++) ans+=d[i];
cout<<ans<<endl;
return 0;
}
//克魯斯卡爾
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#define re register
#define ll long long
using namespace std;
struct rec{int x,y,z;}edge[500010];
int fa[100010],n,m,ans;
bool operator <(rec a,rec b)
{
return a.z<b.z;
}
int get(int x)
{
return fa[x]=(x==fa[x])? x:get(fa[x]);
}
int main()
{
cin>>n>>m;
for(re int i=1;i<=m;i++)
cin>>edge[i].x>>edge[i].y>>edge[i].z;
sort(edge+1,edge+m+1);
for(re int i=1;i<=n;i++) fa[i]=i;
for(re int i=1;i<=m;i++)
{
int x=get(edge[i].x);
int y=get(edge[i].y);
if(x==y) continue;
fa[x]=y;
ans+=edge[i].z;
}
cout<<ans<<endl;
return 0;
}
樹狀陣列
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int n,m;
int a[500005],c[500005];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y)
{
for( ;x<=n;x+=lowbit(x)) c[x]+=y;
}
int ask(int x)
{
int ans=0;
for(;x;x-=lowbit(x)) ans+=c[x];
return ans;
}
int main()
{
}
求乘法逆元
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
long long n,p;
long long inv[3000010];
int main()
{
cin>>n>>p;
inv[1]=1;
printf("1\n");
for(int i=2;i<=n;i++)
{
inv[i]=(long long)(p-p/i)*inv[p%i]%p;
printf("%lld\n",inv[i]);
}
return 0;
}
最近公共祖先
//LCA
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#define re register
#define ll long long
using namespace std;
const int size=50010;
int f[size][20],d[size],dist[size];
int ver[2*size],edge[2*size],next[2*size],head[size];
int T,n,m,tot,t;
queue <int>q;
void add(int x,int y,int z)
{
ver[++tot]=y,edge[tot]=z,next[tot]=head[x],head[x]=tot;
}
void bfs()
{
q.push(1);
d[1]=1;
while(q.size())
{
int x=q.front();
q.pop();
for(re int i=head[x];i;i=next[i]);
{
int y=ver[i],z=edge[i];
if(d[y]) continue
d[y]=d[x]+1;
dist[y]=dist[x]+z;
f[y][0]=x;
for(int j=1;j<=t;j++)
f[y][j]=f[y][f[y][j-1]][j-1];
q.push(y);
}
}
}
int lca(int x,int y)
{
if(d[x]>d[y]) swap(x,y);
for(re int i=t;i>=0;i--)
if(d[f[y][i]]>=d[x]) y=f[y][i];
if(x==y) return x;
for(re int i=t;i>=0;i--)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
int main()
{
cin>>T;
while(T--)
{
cin>>n>>m;
t=(int)(log(n)/log(2))+1;
for(re int i=1;i<=n;i++)
head[i]=d[i]=0;
tot=0;
for(re int i=1;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z),add(y,x,z);
}
bfs();
for(re int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",dist[x]+dist[y]-2*dist[lca(x,y)]);
}
}
return 0;
}
矩陣快速冪
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=1005;
const int mod=1000000007;
struct mat
{
long long m[maxn][maxn];
};
mat a,e;
long long n,p;
mat mul(mat x,mat y)
{
mat c;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
c.m[i][j]=0;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
c.m[i][j]=(c.m[i][j]%mod+(x.m[i][k]*y.m[k][j])%mod)%mod;
}
}
return c;
}
mat pow(mat a,long long b)
{
mat ans=e;
while(b)
{
if(b&1)
ans=mul(ans,a);
a=mul(a,a);
b>>=1;
}
return ans;
}
int main()
{
cin>>n>>p;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cin>>a.m[i][j];
}
for(int i=1;i<=n;i++)
e.m[i][i]=1;
mat s=pow(a,p);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<s.m[i][j]<<" ";
cout<<endl;
}
return 0;
}
nim遊戲
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int t,n;
int main()
{
cin>>t;
while(t--)
{
int ans=0;
cin>>n;
for(int i=1;i<=n;i++)
{
int a;
cin>>a;
ans=ans^a;
}
if(ans)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}