1. 程式人生 > >noip考前模板大整理

noip考前模板大整理

stream 最長回文串 ring 分解質 prior nio check logs sca

//歸並排序求逆序對
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,b[100005];
ll ans;
int a[100005];
void merge_sort(int l,int r) {
    if(l==r)return;
    int mid=(l+r)>>1;
    int i=l,j=mid+1,cnt=l;
    merge_sort(l,mid);
    merge_sort(mid+1,r);
    while(i<=mid&&j<=r) {
        
if(a[i]<=a[j])b[cnt++]=a[i++]; else { b[cnt++]=a[j++]; ans+=(mid-i+1); } } while(i<=mid)b[cnt++]=a[i++]; while(j<=r)b[cnt++]=a[j++]; for(register int s=l; s<=r; ++s)a[s]=b[s]; } int main() { scanf("%d",&n); for
(register int i=1; i<=n; ++i) { scanf("%d",&a[i]); } merge_sort(1,n); printf("%lld",ans); return 0; } //SPFA模板pre為記錄路徑,同dij #include<bits/stdc++.h> using namespace std; int n,m; int pre[50005]; bool book[1505]; int a,b,v,siz; int head[50005],lu[100005]; int cnt,dist[1505
]; struct node { int v,dis,next; } e[50005]; void add(int u,int v,int dis) { ++cnt; e[cnt].v=v; e[cnt].dis=dis; e[cnt].next=head[u]; head[u]=cnt; } void print(int nn) { if(nn==1)return; else { lu[++siz]=pre[nn]; print(pre[nn]); } } void SPFA() { memset(book,false,sizeof(book)); memset(dist,0x3f,sizeof(dist)); queue<int>q; q.push(1); book[1]=1; //pre[1]=0; dist[1]=0; while(!q.empty()) { int u=q.front(); q.pop(); book[u]=0; for(register int i=head[u]; i; i=e[i].next) { int v=e[i].v; if(dist[v]>dist[u]+e[i].dis) { dist[v]=dist[u]+e[i].dis; pre[v]=u; if(!book[v]) { q.push(v); book[v]=1; } } } } } int main() { scanf("%d%d",&n,&m); for(register int i=1; i<=m; ++i) { scanf("%d%d%d",&a,&b,&v); add(a,b,v); } SPFA(); printf("%d\n",dist[n]); print(n); for(register int i=siz; i>=1; --i) printf("%d->",lu[i]); cout<<n; return 0; } //SPFA判負環 int tim[maxn]; bool spfa(int s) { d[s]=0; q.push(s); used[s]=1; while(!q.empty()) { int x=q.front(); q.pop(); used[x]=0; for(int i=first[x]; i; i=next[i]) { int u=hh[i].t; if(d[u]>d[x]+hh[i].c) { d[u]=d[x]+hh[i].c; if(!used[u]) { if(++tim[u]>n) return false; q.push(u); used[u]=1; } } } } return true; } //DIJ模板 #include<iostream> #include<cstdio> #include<cstring> #define maxn 10009 #define inf 2147483647 using namespace std; int n,m,s,sumedge; int dis[maxn],vis[maxn],head[maxn]; struct Edge { //鄰接表儲存 int x,y,z,nxt; Edge(int x=0,int y=0,int z=0,int nxt=0): x(x),y(y),z(z),nxt(nxt) {} } edge[maxn*51]; void add(int x,int y,int z) { edge[++sumedge]=Edge(x,y,z,head[x]); head[x]=sumedge; } void di() { for(int i=1; i<=n; i++)dis[i]=inf; dis[s]=0; for(int i=1; i<=n; i++) { int k,mn=inf; for(int j=1; j<=n; j++) { if(!vis[j]&&dis[j]<mn) { mn=dis[j]; k=j; } } if(mn==inf)break; vis[k]=true; for(int j=head[k]; j; j=edge[j].nxt) { int v=edge[j].y; if(!vis[v]&&dis[v]>dis[k]+edge[j].z) dis[v]=dis[k]+edge[j].z; } } } int main() { scanf("%d%d%d",&n,&m,&s); for(int i=1; i<=m; i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); } di(); for(int i=1; i<=n; i++)printf("%d ",dis[i]); return 0; } //floyd memset(dis,0x3f,sizeof(dis)); for(int i=1; i<=n; i++)dis[i][i]=0; for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); //最小生成樹kruskal #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 5020 #define M 200008 using namespace std; int n,m,ans; int tot; int fa[N]; struct E { int x,y,z; } e[M]; bool cmp(E a,E b) { return a.z<b.z; } int f(int x) { return fa[x]==x?x:fa[x]=f(fa[x]); } int main() { scanf("%d%d",&n,&m); for(int i=1; i<=m; i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z); for(int i=1; i<=n; i++)fa[i]=i; sort(e+1,e+m+1,cmp); for(int i=1; i<=m; i++) { int x=e[i].x,y=e[i].y; int fx=f(x),fy=f(y); if(fx!=fy) { fa[fx]=fy; ans+=e[i].z; if(++tot==n-1)break; } } if(tot!=n-1)cout<<"orz\n"; else printf("%d\n",ans); return 0; } //歐拉篩法 void prime() { check[1]=1; for(int i=2; i<=n; i++) { if(!check[i])prim[++cnt]=i;//這個if語句後面沒有大括號!! for(int j=1; j<=cnt&&prim[j]*i<=n; j++) { check[i*prim[j]]=true; if(i%prim[j]==0)break; } } } //素數判斷 bool check(int x) { if(x<=1)return false; for(int i=2; i*i<=x; i++) if(x%i==0)return false; return true; } //gcd int gcd(int x,int y) { return y==0?x:gcd(y,x%y); } //多組gcd預處理 #include<iostream> #include<cstdio> using namespace std; int n,m,g[100][100]; int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { g[i][i]=i; g[i][0]=g[0][i]=i; for(int j=1; j<i; j++) { g[j][i]=g[i][j]=g[j][i%j]; } } return 0; } //最長回文串 #include<cstdio> #include<cstring> #include<iostream> using namespace std; const int maxn=1e7+5; char s[maxn*2],str[maxn*2]; int Len[maxn*2],len; void getstr() { int k=0; str[k++]=$; for(int i=0; i<len; i++) str[k++]=#, str[k++]=s[i]; str[k++]=#; len=k; } void Manacher() { getstr(); int mx=0,id; for(int i=1; i<len; i++) { if(mx>i) Len[i]=min(Len[2*id-i],mx-i); else Len[i]=1; while(str[i+Len[i]]==str[i-Len[i]]) Len[i]++; if(Len[i]+i>mx) mx=Len[i]+i,id=i; } } int main() { scanf("%s",&s); len=strlen(s); Manacher(); int ans=1; for(int i=1; i<len; i++) ans=max(ans,Len[i]); printf("%d\n",ans-1); return 0; } //分解質因素 #include<iostream> #include<cstdio> #include<cstdlib> using namespace std; int main() { long long n; scanf("%lld",&n); for(long long i=2; i<=n; i++) { while(n!=i) { if(n%i==0) { printf("%lld*",i); n=n/i; } else break; } } printf("%lld",n); return 0; } //求樹上兩點距離,無向圖根節點隨意,有向的根入度為0 #include<bits/stdc++.h> using namespace std; int n; int deep[100005]; int ru[100005]; int fa[100005]; int head[100005],cnt; int dist[100005]; struct node { int v,w,next; } e[200005]; inline void add(int u,int v,int w) { e[++cnt].next=head[u]; e[cnt].v=v; e[cnt].w=w; head[u]=cnt; } inline void Deep_pre(int x,int dep) {//求深度 deep[x]=dep; for(register int i=head[x]; i; i=e[i].next) { if(e[i].v==fa[x]) continue; fa[e[i].v]=x; dist[e[i].v]=dist[x]+e[i].w; Deep_pre(e[i].v,dep+1); } } inline int lca(int x,int y) {//暴力lca if(deep[x]>deep[y])swap(x,y); while(deep[x]!=deep[y]) { y=fa[y]; } while(x!=y) { x=fa[x]; y=fa[y]; } return x; } int main() { scanf("%d",&n); for(register int i=1,u,v,w; i<n; ++i) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } int root=1; fa[root]=0; Deep_pre(root,1); int m,ui,vi; scanf("%d",&m); for(register int i=1; i<=m; ++i) { scanf("%d%d",&ui,&vi); int LCA=lca(ui,vi); // printf("%d\n",deep[ui]+deep[vi]-2*deep[LCA]);//兩點距離 printf("%d\n",dist[ui]+dist[vi]-2*dist[LCA]);//兩點距離 } return 0; } //Tarjan lca #include<bits/stdc++.h> #define ll long long using namespace std; int n,m,s; int head[500005],hd[500005]; int x,y,u,v,cnt,cnt1; bool vis[500005]; int fa[500005],ans[500005]; struct node { int v,next; } e[500005<<1]; struct edge { int v,next,num; } ee[500005<<1]; inline int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } inline void Union(int x,int too) { int r1=find(x),r2=find(too); if(r1!=r2)fa[r2]=r1; } inline void add(int u,int v) { e[++cnt].next=head[u]; e[cnt].v=v; head[u]=cnt; } inline void ask(int u,int v,int num) { ee[++cnt1].next=hd[u]; ee[cnt1].num=num; ee[cnt1].v=v; hd[u]=cnt1; } inline void dfs(int x) { vis[x]=true; for(register int i=hd[x]; i; i=ee[i].next) { if(vis[ee[i].v])ans[ee[i].num]=find(ee[i].v); } for(register int i=head[x]; i; i=e[i].next) { if(!vis[e[i].v]) { dfs(e[i].v); Union(x,e[i].v); } } } int main() { memset(vis,false,sizeof(vis)); scanf("%d%d%d",&n,&m,&s); for(register int i=1; i<=n; ++i)fa[i]=i; for(register int i=1; i<n; ++i) { scanf("%d%d",&x,&y); add(x,y); add(y,x); } for(register int i=1; i<=m; ++i) { scanf("%d%d",&u,&v); ask(u,v,i); ask(v,u,i); } dfs(s); for(register int i=1; i<=m; ++i)printf("%d\n",ans[i]); return 0; } //快速米 ll qpow(ll x,ll y,ll p) { // x^y mod p ll ret=1; while(y) { if(y&1)ret = ret * x % p; x=x*x%p; y>>=1; } return ret; } //圖上dfs int head[10005]={0}; int cnt=0; int vis[10005]; struct edge { int to; int nxt=0; }bian[100005]; void add(int a,int b) { cnt++; bian[cnt].to=b; bian[cnt].nxt=head[a]; head[a]=cnt; } void dfs(int x) { printf("%d\n",x); vis[x]=1; for(int i=head[x];i!=0;i=bian[i].nxt) { if(!vis[bian[i].to]) dfs(bian[i].to); } } dfs(1); //最小環 #include<bits/stdc++.h> #define v (ti[x]) #define ll long long using namespace std; int n,ans(1<<30);int ass=0; bool vis[200005]; int ti[200005],DEP[200005]; inline void dfs(int x,int steps) { if(ass>=300000) { printf("%d\n",ans); exit(0); } ass++; DEP[x]=steps; vis[x]=1; if(DEP[v])ans=min(ans,DEP[x]-DEP[v]+1);//有環了 else dfs(v,steps+1); DEP[x]=0; } int main() { scanf("%d",&n); for(register int i=1; i<=n; ++i) { scanf("%d",&ti[i]); } for(register int i=1; i<=n; ++i) { if(!vis[i])dfs(i,1); } printf("%d\n",ans); return 0; } //堆優化dij #include<cstdio> #include<queue> #include<cstring> #define inf (0x3f3f3f3f) struct node { int cur,x; bool operator<(const node& b) const { return this->x>b.x; } }; struct edge { int v,w,pre; } e[10000000]; std::priority_queue<node> Q; bool inQ[100000]; int dis[10000],cnt; int head[100000]; void adde(int u,int v,int w) { e[++cnt]=(edge) {v,w,head[u]},head[u]=cnt; e[++cnt]=(edge) {u,w,head[v]},head[v]=cnt; } int dij(int s,int t) { memset(dis,0x3f,sizeof dis); dis[s]=0; inQ[s]=1; Q.push((node) {s,0}); while(!Q.empty()) { node me=Q.top(); Q.pop(); inQ[me.cur]=0; if(me.x==inf) continue; for(int i=head[me.cur]; i; i=e[i].pre) { int v=e[i].v; if(dis[v]>dis[me.cur]+e[i].w) { dis[v]=dis[me.cur]+e[i].w; if(!inQ[v]) { inQ[v]=1; Q.push((node) { v,dis[v] }); } } } } return dis[t]==inf?-1:dis[t]; } int main() { int num,u,v,w,s,t; scanf("%d",&num); while(num--) { scanf("%d%d%d",&u,&v,&w); adde(u,v,w); } scanf("%d%d",&s,&t); printf("%d\n",dij(s,t)); return 0; }

noip考前模板大整理