最短路

#include <bits/stdc++.h> using namespace std; const int maxn=1e5+5; const int maxm=2e6+5; const int inf=0x7fffffff; int h[maxn],vis[maxn],dis[maxn]; int tot,n,m,s; struct edge { int u;//next int v;//to int w;//weight }e[maxm]; struct node { int now; int w; bool operator<(const node&a)const { return w>a.w; } }; inline void add(int u,int v,int w) { tot++; e[tot].v=v; e[tot].w=w; e[tot].u=h[u]; h[u]=tot; } inline void dijkstra() { for(int i=1;i<=n;++i) { dis[i]=inf; } dis[s]=0; priority_queue<node> que; que.push((node){s,0}); while(!que.empty()) { node x=que.top(); que.pop(); int u=x.now; if(vis[u])continue; vis[u]=1; for(int i=h[u];i;i=e[i].u) { int v=e[i].v; if(dis[v]>dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; que.push((node){v,dis[v]}); } } } } int main() { scanf("%d%d%d",&n,&m,&s); for(int i=1;i<=m;++i) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } dijkstra(); for(int i=1;i<=n;++i) { printf("%d ",dis[i]); } return 0; }
最小生成树

#include <bits/stdc++.h> using namespace std; const int inf=0x7fffffff; const int maxn=5e3+5; const int maxm=2e5+5; int h[maxn],dis[maxn],vis[maxn]; int n,m,tot,cnt,ans,now=1; struct edge { int u; int v; int w; }e[maxm<<1]; inline void add(int u,int v,int w) { tot++; e[tot].v=v; e[tot].w=w; e[tot].u=h[u]; h[u]=tot; } inline int prim() { for(int i=2;i<=n;++i) { dis[i]=inf; } for(int i=h[1];i;i=e[i].u) { dis[e[i].v]=min(dis[e[i].v],e[i].w); } while(++cnt<n) { int mmin=inf; vis[now]=1; for(int i=1;i<=n;++i) { if(!vis[i]&&mmin>dis[i]) { mmin=dis[i]; now=i; } } ans+=mmin; for(int i=h[now];i;i=e[i].u) { int v=e[i].v; if(!vis[v]&&dis[v]>e[i].w) { dis[v]=e[i].w; } } } return ans; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } printf("%d\n",prim()); return 0; }

#include <bits/stdc++.h> using namespace std; const int inf=0x7fffffff; const int maxn=5e3+5; const int maxm=2e5+5; int f[maxn]; int n,m,eu,ev,cnt,ans; struct edge { int u; int v; int w; }e[maxm]; inline bool cmp(const edge&a,const edge&b) { return a.w<b.w; } inline int find_(int x) { return f[x]==x?x:f[x]=find_(f[x]); } inline void kruskal() { sort(e+1,e+m+1,cmp); for(int i=1;i<=m;++i) { eu=find_(e[i].u); ev=find_(e[i].v); if(eu==ev)continue; ans+=e[i].w; f[ev]=eu; if(++cnt==n-1)break; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i)f[i]=i; for(int i=1;i<=m;++i) { scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); } kruskal(); printf("%d\n",ans); return 0; }
字符串

#pragma GCC optimize(2) #include <bits/stdc++.h> using namespace std; const int N=1e6+5; int kmp[N]; char a[N],b[N]; int main() { scanf("%s%s",a+1,b+1); int alen=strlen(a+1); int blen=strlen(b+1); for(int i=2,j=0;i<=blen;++i) { while(j&&b[i]!=b[j+1])j=kmp[j]; if(b[i]==b[j+1])j++; kmp[i]=j; } for(int i=1,j=0;i<=alen;++i) { while(j&&a[i]!=b[j+1])j=kmp[j]; if(a[i]==b[j+1])j++; if(j==blen) { printf("%d\n",i-blen+1); j=kmp[j]; } } for(int i=1;i<blen;++i) { printf("%d ",kmp[i]); } printf("%d\n",kmp[blen]); return 0; }

#pragma GCC optimize(2) #include <bits/stdc++.h> using namespace std; const int N=1e5+5; int tree[N][30]; bool flag[N]; int tot; inline bool insert_(string s) { int len=s.size(); int rt=0; int id; for(int i=0;i<len;++i) { if(s[i]>='a'&&s[i]<='z')id=s[i]-'a'; if(tree[rt][id]==0)tree[rt][id]=++tot; rt=tree[rt][id]; } int mark=flag[rt]; flag[rt]=1; return !mark; } inline bool find_(char *s) { int len=strlen(s); int rt=0; int id; for(int i=0;i<len;++i) { if(s[i]>='a'&&s[i]<='z')id=s[i]-'a'; if(tree[rt][id]==0)return 0; rt=tree[rt][id]; } return flag[rt]; } int main() { ios::sync_with_stdio(false); while(1) { tot=0; memset(tree,0,sizeof(tree)); memset(flag,0,sizeof(flag)); int ans=0; string a; getline(cin,a); stringstream ss(a); int i=0; while(ss>>a) { if(a[0]=='#'&&i==0)return 0; ans+=insert_(a); ++i; } printf("%d\n",ans); } }

#include <bits/stdc++.h> using namespace std; const int N=61100000; char a[N],s[N<<1]; int n,hw[N],mmax=1; inline void change() { s[0]=s[1]='#'; for(int i=0;i<n;++i) { s[i*2+2]=a[i]; s[i*2+3]='#'; } n=n*2+2; s[n]=0; } void manacher() { int maxright=0,mid; for(int i=1;i<n;i++) { if(i<maxright)hw[i]=min(hw[(mid<<1)-i],maxright-i); else hw[i]=1; for(;s[i+hw[i]]==s[i-hw[i]];++hw[i]); if(hw[i]+i>maxright) { maxright=hw[i]+i; mid=i; } mmax=max(mmax,hw[i]); } } int main() { scanf("%s",a); n=strlen(a); change(); manacher(); cout<<mmax-1; return 0; }

#include <bits/stdc++.h> #define maxn 1000005 using namespace std; int tree[maxn][26]; int val[maxn]; int fail[maxn]; int cnt=0; inline void build(char *s) { int len=strlen(s); int now=0; for(int i=0;i<len;++i) { int v=s[i]-'a'; if(tree[now][v]==0)tree[now][v]=++cnt; now=tree[now][v]; } val[now]++; } inline void get_fail() { queue<int>q; for(int i=0;i<26;++i) { if(tree[0][i]) { fail[tree[0][i]]=0; q.push(tree[0][i]); } } while(!q.empty()) { int u=q.front(); q.pop(); for(int i=0;i<26;++i) { if(tree[u][i]) { fail[tree[u][i]]=tree[fail[u]][i]; q.push(tree[u][i]); } else tree[u][i]=tree[fail[u]][i]; } } } inline int ac_query(char *s) { int len=strlen(s); int now=0,ans=0; for(int i=0;i<len;++i) { now=tree[now][s[i]-'a']; for(int k=now;k&&val[k]!=-1;k=fail[k]) { ans+=val[k]; //val[k]=-1; } } return ans; } struct sss { char s[10001]; }ss[100003]; char str[maxn]; int main() { int t,n; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); memset(val,0,sizeof(val)); memset(tree,0,sizeof(tree)); memset(fail,0,sizeof(fail)); for(int i=1;i<=n;++i) { scanf("%s",ss[i].s); } for(int i=1;i<=m;++i) { scanf("%s",str); build(str); } get_fail(); for(int i=1;i<=n;++i) { printf("%d\n",ac_query(ss[i].s)); } } return 0; } /* 5 she he say shr her yasherhs */
ST表

#pragma GCC optimize(2) #include <bits/stdc++.h> using namespace std; int st[50][100010]; inline int Max(int a,int b) { return a>b?a:b; } int main() { ios::sync_with_stdio(false); int n,m; cin>>n>>m; for(int i=1;i<=n;++i) { cin>>st[0][i]; } int t=log2(n); for(int i=1;i<=t;++i) { for(int j=1;j+(1<<i)-1<=n;++j) { st[i][j]=Max(st[i-1][j],st[i-1][j+(1<<(i-1))]); } } while(m--) { int l,r; cin>>l>>r; int t=log2(r-l+1); cout<<Max(st[t][l],st[t][r-(1<<t)+1])<<endl; } return 0; }
矩阵快速幂

#include <bits/stdc++.h> using namespace std; const int MOD=1e9+7; const int maxn=110; typedef long long ll; ll n,kk; struct mat { ll m[maxn][maxn]; }c,d,e,o; inline mat mul(const mat &a,const mat &b) { mat ret=o; for(int i=1;i<=3;++i) { for(int j=1;j<=3;++j) { for(int k=1;k<=3;++k) { ret.m[i][j]=(ret.m[i][j]+a.m[i][k]*b.m[k][j]%MOD)%MOD; } } } return ret; } inline mat qpow(mat x,ll y) { mat ans=e; while(y) { if(y&1)ans=mul(ans,x); x=mul(x,x); y>>=1; } return ans; } int main() { scanf("%lld",&n); for(int i=1;i<=3;++i) { for(int j=1;j<=3;++j) { o.m[i][j]=0; } e.m[i][i]=1; } d=o; d.m[1][1]=1; d.m[1][2]=1; d.m[2][3]=1; d.m[3][1]=1; c=o; c.m[1][1]=1; c.m[1][2]=1; c.m[1][3]=1; for(int i=1;i<=n;++i) { scanf("%lld",&kk); if(kk<3) { printf("1\n"); continue; } mat ans=qpow(d,kk-3); ans=mul(c,ans); printf("%lld\n",ans.m[1][1]); } return 0; }

#include <cstdio> #include <iostream> using namespace std; typedef long long ll; const int n=1e6+5; int vis[n],phi[n],p[n],cnt; ll ans[n]; ll oula(ll n) { ll res=n; for(ll i=2;i*i<=n;++i) { if(n%i==0)res=res/i*(i-1); while(n%i==0)n/=i; } if(n>1)res=res/n*(n-1); return res; } void oulashai() { phi[1]=1; for(int i=2;i<=n;++i) { if(vis[i]==0)//i为素数 { p[++cnt]=i;//将i加入素数数组p中 phi[i]=i-1;//因为i是素数,由特性得知 } for(int j=1;j<=cnt&&i*p[j]<=n;++j) //用当前已得到的素数数组p筛,筛去p[j]*i { vis[i*p[j]]=1;//可以确定i*p[j]不是素数 if(i%p[j]==0) //看p[j]是否是i的约数,因为素数p[j],等于判断i和p[j]是否互质 { phi[i*p[j]]=phi[i]*p[j]; //特性2 break; } else phi[i*p[j]]=phi[i]*phi[p[j]];//(p[j]-1); //互质,特性3其,p[j]-1就是phi[p[j]] } } } //m[i]标记i是否为素数,0为素数,1不为素数;p是存放素数的数组;nump是当前素数个数;phi[i]为欧拉函数 int main() { oulashai(); int t; for(int i=1;i<=n;++i) { ans[i]=ans[i-1]+phi[i]; } while(~scanf("%d",&t)&&t) { cout<<ans[t]-1<<endl; } return 0; }
数论

#include<bits/stdc++.h> using namespace std; typedef long long ll; int n; ll f[50]; ll c[50][50]; ll ff[40]; inline void init() { f[1]=0; f[2]=1; for(int i=3;i<=35;++i) { f[i]=(i-1)*(f[i-1]+f[i-2]); } c[0][0]=1; for(int i=1;i<=35;++i) { for(int j=0;j<=i;++j) { c[i][j]=c[i-1][j-1]+c[i-1][j]; } } ff[0]=ff[1]=1; for(int i=2;i<=35;++i) { for(int j=0;j<i;++j) { ff[i]+=ff[j]*ff[i-j-1]; } } } int main() { init(); int t; int cnt=0; while(~scanf("%d",&t)) { if(t==-1)break; printf("%d %d %lld\n",++cnt,t,ff[t]*2); } return 0; }
树

#pragma GCC optimize(2) #include <bits/stdc++.h> #define lowbit(i)(i&(-i)) #define Max(a,b)(((a)>(b))?(a):(b)) #define Min(a,b)(((a)<(b))?(a):(b)) using namespace std; const int maxn=200010; typedef long long ll; ll a[maxn];//原数据 ll c1[maxn];//记录区间增量 ll c2[maxn]; ll asum[maxn];//差分原数据 ll mmax[maxn]; ll mmin[maxn]; int n,m; inline void add(ll *arr,int x,ll val)//修改节点 { while(x<=n) { arr[x]+=val; x+=lowbit(x); } } inline void qj_add(int l,int r,ll val)//区间修改 运用了差分的思想 { add(c1,l,val); add(c1,r+1,-val); add(c2,l,val*l);//*1 add(c2,r+1,-val*(r+1)); } inline ll sum(ll *arr,ll x) { ll ans=0; while(x) { ans+=arr[x]; x-=lowbit(x); } return ans; } inline ll F(int x) { return asum[x]+(x+1)*sum(c1,x)-sum(c2,x); } inline ll query(int l,int r)//区间查询 { return F(r)-F(l-1); } inline int max_query(int l,int r) { int ans=a[r]; while(l!=r) { r--; while(r-l>=lowbit(r)) { ans=Max(ans,mmax[r]); r-=lowbit(r); } ans=Max(ans,a[r]); } return ans; } inline int min_query(int l,int r) { int ans=a[r]; while(l!=r) { r--; while(r-l>=lowbit(r)) { ans=Min(ans,mmin[r]); r-=lowbit(r); } ans=Min(ans,a[r]); } return ans; } inline void update(int x,ll val) { a[x]=val; while(x<=n) { mmax[x]=a[x]; mmin[x]=a[x]; for(int j=1;j<lowbit(x);j<<=1) { mmax[x]=Max(mmax[x],mmax[x-j]); mmin[x]=Min(mmin[x],mmin[x-j]); } x+=lowbit(x); } }

#include <bits/stdc++.h> using namespace std; const int maxn=200005; typedef long long ll; double sum[maxn<<2]; double pls[maxn<<2]; double mul[maxn<<2]; int n,m; inline void pushup(int rt)//往上更新区间和 { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } inline void build(int rt,int l,int r) { if(l==r) { scanf("%lf",&sum[rt]); return; } mul[rt]=1; int mid=(l+r)>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); pushup(rt); } inline void pushdown(int rt,int l,int r) { int mid=(l+r)>>1; sum[rt<<1]*=mul[rt]; mul[rt<<1]*=mul[rt]; pls[rt<<1]*=mul[rt]; sum[rt<<1|1]*=mul[rt]; mul[rt<<1|1]*=mul[rt]; pls[rt<<1|1]*=mul[rt]; sum[rt<<1]+=pls[rt]*(mid-l+1); pls[rt<<1]+=pls[rt]; sum[rt<<1|1]+=pls[rt]*(r-mid); pls[rt<<1|1]+=pls[rt]; pls[rt]=0; mul[rt]=1; } inline void add_qj(int rt,int l,int r,int ql,int qr,double k)//区间加 { if(ql<=l&&r<=qr) { sum[rt]+=k*(r-l+1); pls[rt]+=k; return; } pushdown(rt,l,r); int mid=(l+r)>>1; if(ql<=mid)add_qj(rt<<1,l,mid,ql,qr,k); if(qr>mid)add_qj(rt<<1|1,mid+1,r,ql,qr,k); pushup(rt); } inline void mul_qj(int rt,int l,int r,int ql,int qr,double k)//区间乘 { if(ql<=l&&r<=qr) { sum[rt]*=k; mul[rt]*=k; pls[rt]*=k; return; } pushdown(rt,l,r); int mid=(l+r)>>1; if(ql<=mid)mul_qj(rt<<1,l,mid,ql,qr,k); if(qr>mid)mul_qj(rt<<1|1,mid+1,r,ql,qr,k); pushup(rt); } double query(int rt,int l,int r,int ql,int qr)//单点查询 { if(ql<=l&&r<=qr)return sum[rt]; pushdown(rt,l,r); int mid=(l+r)>>1; double sum1=0,sum2=0; if(ql<=mid)sum1+=query(rt<<1,l,mid,ql,qr); if(qr>mid)sum2+=query(rt<<1|1,mid+1,r,ql,qr); return sum1+sum2; } int main() { scanf("%d%d",&n,&m); build(1,1,n); while(m--) { int opt; scanf("%d",&opt); if(opt==1) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); double l1=b-a+1,l2=d-c+1; double s1=query(1,1,n,a,b); double s2=query(1,1,n,c,d); mul_qj(1,1,n,a,b,(l1-1)/l1); mul_qj(1,1,n,c,d,(l2-1)/l2); add_qj(1,1,n,a,b,1.0/l1*(s2/l2)); add_qj(1,1,n,c,d,1.0/l2*(s1/l1)); } else { int a,b; scanf("%d%d",&a,&b); printf("%.5f\n",query(1,1,n,a,b)); } } return 0; }

#pragma GCC optimize(2) #include <bits/stdc++.h> #define Max(a,b)(((a)>(b))?(a):(b)) using namespace std; const int maxn=100010; const int inf=0x3f3f3f3f; int f[maxn],c[maxn],w[maxn]; inline void completepack(int v,int w,int m) { for(int j=v;j<=m;++j) { f[j]=Max(f[j],f[j-v]+w); } } inline void zeroonepack(int v,int w,int m) { for(int j=m;j>=v;--j) { f[j]=Max(f[j],f[j-v]+w); } } inline void multipack(int v,int w,int m,int c) { if(v*c>m) { completepack(v,w,m); } else { int k=1; while(k<c) { zeroonepack(k*v,k*w,m); c-=k; k*=2; } zeroonepack(c*v,c*w,m); } } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0) { return 0; } memset(f,0,sizeof(f)); for(int i=1;i<=n;++i) { scanf("%d",&w[i]);// } for(int i=1;i<=n;++i) { scanf("%d",&c[i]);// } for(int i=1;i<=n;++i) { multipack(w[i],w[i],m,c[i]); } int sum=0; for(int i=1;i<=m;++i) { if(f[i]==i) { ++sum; } } printf("%d\n",sum);/// } return 0; }