【NOIP模板汇总】I Am Me
I Am Me
kmp
洛谷3375
#include<bits/stdc++.h> using namespace std; #define N 1000100 char a[N],b[N]; int n,m,fail[N]; int main() { scanf("%s%s",b+1,a+1); n=strlen(a+1); for(int i=2,j=0;i<=n;i++) { while(j>0&&a[i]!=a[j+1])j=fail[j]; if(a[i]==a[j+1])j++; fail[i]=j; } m=strlen(b+1); for(int i=1,j=0;i<=m;i++) { while(j>0&&(j==n||b[i]!=a[j+1]))j=fail[j]; if(b[i]==a[j+1])j++; if(j==n) { printf("%d\n",i-n+1); j=fail[j]; } } for(int i=1;i<=n;i++)printf("%d ",fail[i]); return 0; }
堆优化dijkstra
洛谷4779
#include<bits/stdc++.h> using namespace std; #define ll long long #define mp make_pair #define N 100100 typedef pair<ll,ll>pii; ll n,m,s,cnt,ans; ll d[N],vis[N],first[N]; struct email { ll u,v,w; ll nxt; }e[N*4]; inline void add(ll u,ll v,ll w) { e[++cnt].nxt=first[u];first[u]=cnt; e[cnt].u=u;e[cnt].v=v;e[cnt].w=w; } priority_queue<pii>q; void dijkstra(ll s) { memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(d)); d[s]=0; q.push(mp(-d[s],s)); while(!q.empty()) { pii x=q.top();q.pop(); ll u=x.second,now=x.first; if(vis[u])continue;vis[u]=1; for(ll i=first[u];i;i=e[i].nxt) { ll v=e[i].v,w=e[i].w; if(d[v]>d[u]+w) { d[v]=d[u]+w; q.push(mp(-d[v],v)); } } } } int main() { scanf("%lld%lld%lld",&n,&m,&s); for(ll i=1;i<=m;i++) { ll u,v,w; scanf("%lld%lld%lld",&u,&v,&w); add(u,v,w); } dijkstra(s); for(ll i=1;i<=n;i++)printf("%lld ",d[i]); return 0; }
快速幂
洛谷1226
#include<bits/stdc++.h> using namespace std; #define ll long long ll a,b,mod; inline ll ksm(ll a,ll b) { ll ret=1,tmp=b; while(b) { if(b&1)ret=(ret*a)%mod; a=(a*a)%mod; b>>=1; } return (tmp!=0)?ret:0; } int main() { cin>>a>>b>>mod; cout<<a<<"^"<<b<<" mod "<<mod<<"="<<ksm(a,b); }
矩阵快速幂
洛谷3390
#include<bits/stdc++.h> using namespace std; #define N 110 #define ll long long #define mod 1000000007 ll n,k; struct email { ll x[N][N]; }a,ans; inline email mul(email a,email b) { email c; memset(c.x,0,sizeof(c.x)); for(ll i=1;i<=n;i++) for(ll j=1;j<=n;j++) for(ll k=1;k<=n;k++) c.x[i][j]=(c.x[i][j]+a.x[i][k]*b.x[k][j])%mod; return c; } inline email ksm(email a,ll k) { if(k==1)return a; email b=ksm(a,k/2); b=mul(b,b); if(k&1)b=mul(b,a); return b; } int main() { scanf("%lld%lld",&n,&k); for(ll i=1;i<=n;i++) for(ll j=1;j<=n;j++) scanf("%lld",&a.x[i][j]); ans=ksm(a,k); for(ll i=1;i<=n;i++) { for(ll j=1;j<=n;j++) printf("%lld ",ans.x[i][j]); printf("\n"); } }
并查集
洛谷3367
#include<bits/stdc++.h> using namespace std; #define N 10010 int n,m; int fa[N]; inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} inline void combine(int x,int y){fa[find(x)]=find(y);} int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++) { int op,x,y; scanf("%d%d%d",&op,&x,&y); if(op==1)combine(x,y); else { if(find(x)==find(y))puts("Y"); else puts("N"); } } return 0; }
Kruskal
洛谷3366
#include<bits/stdc++.h> using namespace std; #define N 10010 int n,m,cnt,tot,ans; int fa[N]; struct email { int u,v,w; }e[N*40]; inline void add(int u,int v,int w){e[++cnt].u=u;e[cnt].v=v;e[cnt].w=w;} inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} inline void combine(int x,int y){fa[find(x)]=find(y);} bool cmp(email a,email b){return a.w<b.w;} void kruskal() { for(int i=1;i<=m;i++) { int u=e[i].u,v=e[i].v,w=e[i].w,fax=find(u),fay=find(v); if(fax!=fay)fa[fax]=fay,++tot,ans+=w; if(tot==n-1)break; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } sort(e+1,e+1+m,cmp); kruskal(); if(tot!=n-1)puts("orz"); else printf("%d",ans); return 0; }
割点
洛谷3388
#include<bits/stdc++.h> using namespace std; #define N 50050 int n,m,cnt,tot,ans,root,child; int dfn[N],low[N],cut[N],first[N]; struct email { int u,v; int nxt; }e[N*4]; inline void add(int u,int v) { e[++cnt].nxt=first[u];first[u]=cnt; e[cnt].u=u;e[cnt].v=v; } inline void tarjan(int u,int fa) { dfn[u]=low[u]=++tot;child=0; for(int i=first[u];i;i=e[i].nxt) { int v=e[i].v; if(v==fa)continue; if(!dfn[v]) { tarjan(v,u); low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]&&u!=root) cut[u]=1; if(u==root) child++; } else low[u]=min(low[u],dfn[v]); } if(u==root&&child>1)cut[u]=1; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u); } for(int i=1;i<=n;i++) if(!dfn[i]) root=i,tarjan(i,i); for(int i=1;i<=n;i++)ans+=cut[i]; printf("%d\n",ans); for(int i=1;i<=n;i++) if(cut[i]) printf("%d ",i); return 0; }
割边
#include<bits/stdc++.h> using namespace std; #define N 50050 int n,m,cnt,tot,ans,cot; int dfn[N],low[N],first[N]; struct email { int u,v; int nxt; }e[N*4],cut[N*4]; inline void add(int u,int v) { e[++cnt].nxt=first[u];first[u]=cnt; e[cnt].u=u;e[cnt].v=v; } inline void tarjan(int u,int fa) { dfn[u]=low[u]=++tot; for(int i=first[u];i;i=e[i].nxt) { int v=e[i].v; if(v==fa)continue; if(!dfn[v]) { tarjan(v,u); low[u]=min(low[u],low[v]); if(low[v]>dfn[u])cut[++cot]=e[i]; } else low[u]=min(low[u],dfn[v]); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i); for(int i=1;i<=cot;i++) { int u=cut[i].u,v=cut[i].v; printf("%d-->%d\n",u,v); } return 0; }
缩点
#include<bits/stdc++.h> using namespace std; #define N 50050 int n,m,cnt,tot,ans,gro; int dfn[N],low[N],col[N],siz[N],vis[N],first[N]; stack<int>s; struct email { int u,v; int nxt; }e[N*4]; inline void add(int u,int v) { e[++cnt].nxt=first[u];first[u]=cnt; e[cnt].u=u;e[cnt].v=v; } inline void tarjan(int u) { dfn[u]=low[u]=++tot; s.push(u);vis[u]=1; for(int i=first[u];i;i=e[i].nxt) { int v=e[i].v; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]) { ++gro; while(1) { int t=s.top();s.pop();vis[t]=0; col[t]=gro;siz[gro]++; if(t==u)break; } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) printf("%d ",col[i]); return 0; }
Floyd
for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) e[i][j]=min(e[i][j],e[i][k]+e[k][j]);
逆元
#include<bits/stdc++.h> using namespace std; #define N 3000030 #define ll long long ll b,mod; ll inv[N]; int main() { scanf("%lld%lld",&b,&mod); inv[1]=1; for(ll i=2;i<=b;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod; for(ll i=1;i<=b;i++) printf("%lld\n",inv[i]); return 0; }
exgcd
#include<bits/stdc++.h> using namespace std; int b,x,y,mod,gcd; inline int exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1,y=0; return a; } int ret=exgcd(b,a%b,x,y); int t=x;x=y,y=t-(a/b)*y; return ret; } int main() { cin>>b>>mod; gcd=exgcd(b,mod,x,y); if(gcd!=1)printf("not exist\n"); else printf("%d\n",(x%mod+mod)%mod); return 0; }
线性筛
#include<bits/stdc++.h> using namespace std; #define N 10000010 int n,m,cnt; int prime[N],v[N]; void primes(int n) { for(int i=2;i<=n;i++) { if(!v[i]) { v[i]=i; prime[++cnt]=i; } for(int j=1;j<=cnt;j++) { if(prime[j]*i>n||prime[j]>i)break; v[prime[j]*i]=prime[j]; } } } int main() { scanf("%d%d",&n,&m); primes(n); while(m--) { int x; scanf("%d",&x); if(v[x]==x)printf("Yes\n"); else printf("No\n"); } return 0; }
欧拉函数
#include<bits/stdc++.h> using namespace std; #define N 10000010 int n,m,cnt; int prime[N],phi[N],v[N]; void primes(int n) { for(int i=2;i<=n;i++) { if(!v[i]) { v[i]=i; prime[++cnt]=i; phi[i]=i-1; } for(int j=1;j<=cnt;j++) { if(prime[j]*i>n||prime[j]>i)break; v[prime[j]*i]=prime[j]; phi[i*prime[j]]=phi[i]*((i%prime[j])?(prime[j]-1):prime[j]); } } } int main() { scanf("%d",&n); primes(n); for(int i=1;i<=n;i++)printf("%d ",phi[i]); return 0; }
埃拉托色尼筛
#include<bits/stdc++.h> using namespace std; #define N 1000010 int n,m,cnt; int prime[N],v[N]; void primes(int n) { for(int i=2;i<=n;i++) { if(!v[i]) { prime[++cnt]=i; for(int j=i*i;j<=n;j+=i) v[j]=1; } } } int main() { scanf("%d",&n); primes(n); for(int i=1;i<=cnt;i++)printf("%d ",prime[i]); return 0; }
中国剩余定理
#include<bits/stdc++.h> using namespace std; #define N 20 #define ll long long ll n,x,y,ans; ll a[N],m[N]; inline ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1,y=0; return a; } ll ret=exgcd(b,a%b,x,y); ll t=x;x=y,y=t-(a/b)*y; return ret; } inline ll CRT(ll a[],ll m[],ll n) { ll ans=0,M=1; for(ll i=1;i<=n;i++)M*=m[i]; for(ll i=1;i<=n;i++) { ll Mi=M/m[i]; exgcd(Mi,m[i],x,y); ans=(ans+x*a[i]*Mi)%M; } if(ans<0)ans+=M; return ans; } int main() { scanf("%lld",&n); for(ll i=1;i<=n;i++)scanf("%lld%lld",&m[i],&a[i]); ans=CRT(a,m,n); printf("%lld\n",ans); return 0; }
扩展中国剩余定理
#include<bits/stdc++.h> using namespace std; #define N 1000010 #define ll long long ll n,x,y,ans,flag; ll c[N],m[N]; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1,y=0; return a; } ll ret=exgcd(b,a%b,x,y); ll t=x;x=y,y=t-(a/b)*y; return ret; } inline ll inv(ll a,ll b){ll tmp=exgcd(a,b,x,y);return x=(x%b+b)%b;} int main() { while(scanf("%lld",&n)==1) { for(ll i=1;i<=n;i++)scanf("%lld%lld",&m[i],&c[i]); flag=1; for(ll i=2;i<=n;i++) { ll c1=c[i-1],m1=m[i-1],c2=c[i],m2=m[i],d=gcd(m1,m2); if((c2-c1)%d){flag=0;break;} m[i]=(m1*m2)/d; c[i]=(inv(m1/d,m2/d)*(c2-c1)/d)%(m2/d)*m1+c1; c[i]=(c[i]%m[i]+m[i])%m[i]; } printf("%lld\n",flag?c[n]:-1); } return 0; }
LCA
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 10100 int n,t,x,y,cnt,root; int first[N],in[N],dep[N]; int fa[N][20]; struct email { int u,v; int nxt; }e[N*4]; inline void add(int u,int v) { e[++cnt].nxt=first[u];first[u]=cnt; e[cnt].u=u;e[cnt].v=v; } void dfs(int u,int f) { for(int i=1;(1<<i)<=dep[u];i++) fa[u][i]=fa[fa[u][i-1]][i-1]; for(int i=first[u];i;i=e[i].nxt) { int v=e[i].v; if(v==f)continue; fa[v][0]=u; dep[v]=dep[u]+1; dfs(v,u); } } int lca(int x,int y) { if(dep[x]<dep[y]) swap(x,y); int k=dep[x]-dep[y]; for(int i=0;(1<<i)<=k;i++) if(k&(1<<i)) x=fa[x][i]; if(x==y)return x; for(int i=19;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } inline void init() { memset(in,0,sizeof(in)); memset(dep,0,sizeof(dep)); memset(first,0,sizeof(first)); memset(fa,0,sizeof(fa)); cnt=0; } int main() { scanf("%d",&t); while(t--) { init(); scanf("%d",&n); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u);in[v]++; } for(int i=1;i<=n;i++) if(!in[i]) {root=i;break;} dfs(root,0); scanf("%d%d",&x,&y); printf("%d\n",lca(x,y)); } }
树的直径
inline void dfs(int u,int fa) { for(int i=first[u];i;i=e[i].nxt) { int v=e[i].v,w=e[i].w; if(v==fa)continue; d[v]=d[u]+w; dfs(v,u); } } int main() { ... memset(d,0x3f,sizeof(d)); d[x]=0; dfs(x,x); for(int i=1;i<=n;i++) if(maxx<d[i]) maxx=d[i],p=i; memset(d,0x3f,sizeof(d)); d[p]=0; dfs(p,p); for(int i=1;i<=n;i++) dia=max(dia,d[i]); ... }
线段树
区间加
#include<bits/stdc++.h> using namespace std; #define N 100100 #define lc (p<<1) #define rc (p<<1|1) #define ll long long #define mid (t[p].l+t[p].r>>1) ll n,m; ll a[N]; struct email { ll l,r,sum,lazy; }t[N*4]; inline void pushnow(ll p,ll v) { t[p].lazy+=v; t[p].sum+=(t[p].r-t[p].l+1)*v; } inline void pushup(ll p) { t[p].sum=t[lc].sum+t[rc].sum; } inline void pushdown(ll p) { if(t[p].lazy) { pushnow(lc,t[p].lazy); pushnow(rc,t[p].lazy); t[p].lazy=0; } } inline void build(ll p,ll l,ll r) { t[p].l=l,t[p].r=r; if(l==r) { t[p].sum=a[l]; return ; } ll bm=l+r>>1; build(lc,l,bm);build(rc,bm+1,r); pushup(p); } inline void update(ll p,ll ql,ll qr,ll v) { if(ql<=t[p].l&&qr>=t[p].r) { pushnow(p,v); return ; } pushdown(p); if(ql<=mid)update(lc,ql,qr,v); if(qr>mid)update(rc,ql,qr,v); pushup(p); } inline ll query(ll p,ll ql,ll qr) { ll ret=0; if(ql<=t[p].l&&qr>=t[p].r) return t[p].sum; pushdown(p); if(ql<=mid)ret+=query(lc,ql,qr); if(qr>mid)ret+=query(rc,ql,qr); return ret; } int main() { scanf("%lld%lld",&n,&m); for(ll i=1;i<=n;i++)scanf("%lld",&a[i]); build(1,1,n); for(ll i=1;i<=m;i++) { ll op,x,y,k; scanf("%lld%lld%lld",&op,&x,&y); if(op==1) { scanf("%lld",&k); update(1,x,y,k); } else printf("%lld\n",query(1,x,y)); } }
区间乘和区间加
维护两个lazy标记,优先更新乘法标记
#include<bits/stdc++.h> using namespace std; #define N 100100 #define lc (p<<1) #define rc (p<<1|1) #define ll long long #define mid (t[p].l+t[p].r>>1) ll n,m,mod; ll a[N]; struct email { ll l,r,sum,mul,add; }t[N*4]; inline void pushmul(ll p,ll v) { t[p].sum=(t[p].sum*v)%mod; t[p].add=(t[p].add*v)%mod; t[p].mul=(t[p].mul*v)%mod; } inline void pushadd(ll p,ll v) { t[p].add+=v;t[p].add%=mod; t[p].sum+=(t[p].r-t[p].l+1)*v%mod; } inline void pushup(ll p) { t[p].sum=(t[lc].sum+t[rc].sum)%mod; } inline void pushdown(ll p) { if(t[p].mul!=1) { pushmul(lc,t[p].mul); pushmul(rc,t[p].mul); t[p].mul=1; } if(t[p].add) { pushadd(lc,t[p].add); pushadd(rc,t[p].add); t[p].add=0; } } inline void build(ll p,ll l,ll r) { t[p].l=l,t[p].r=r;t[p].mul=1; if(l==r) { t[p].sum=a[l]; return ; } ll bm=l+r>>1; build(lc,l,bm);build(rc,bm+1,r); t[p].sum%=mod; pushup(p); } inline void update(ll p,ll ql,ll qr,ll v) { if(ql<=t[p].l&&qr>=t[p].r) { pushadd(p,v); return ; } pushdown(p); if(ql<=mid)update(lc,ql,qr,v); if(qr>mid)update(rc,ql,qr,v); pushup(p); } inline void update1(ll p,ll ql,ll qr,ll v) { if(ql<=t[p].l&&qr>=t[p].r) { pushmul(p,v); return ; } pushdown(p); if(ql<=mid)update1(lc,ql,qr,v); if(qr>mid)update1(rc,ql,qr,v); pushup(p); } inline ll query(ll p,ll ql,ll qr) { ll ret=0; if(ql<=t[p].l&&qr>=t[p].r) return t[p].sum; pushdown(p); if(ql<=mid)ret=(ret+query(lc,ql,qr))%mod; if(qr>mid)ret=(ret+query(rc,ql,qr))%mod; return ret; } int main() { scanf("%lld%lld%lld",&n,&m,&mod); for(ll i=1;i<=n;i++)scanf("%lld",&a[i]); build(1,1,n); for(ll i=1;i<=m;i++) { ll op,x,y,k; scanf("%lld%lld%lld",&op,&x,&y); if(op==1) { scanf("%lld",&k); update1(1,x,y,k); } else if(op==2) { scanf("%lld",&k); update(1,x,y,k); } else printf("%lld\n",query(1,x,y)); } }
树链剖分
#include<bits/stdc++.h> using namespace std; #define N 100100 #define lc (p<<1) #define rc (p<<1|1) #define ll long long #define mid (t[p].l+t[p].r>>1) ll n,m,cnt,tot,mod,root; ll a[N],d[N],f[N],rk[N],id[N],top[N],siz[N],son[N],first[N]; struct email { ll u,v; ll nxt; }e[N*4]; struct tree { ll l,r,sum,lazy; }t[N*4]; inline void add(ll u,ll v) { e[++cnt].nxt=first[u];first[u]=cnt; e[cnt].u=u;e[cnt].v=v; } inline void pushnow(ll p,ll v) { t[p].lazy+=v; t[p].sum=t[p].sum+(t[p].r-t[p].l+1)*v%mod; } inline void pushup(ll p) { t[p].sum=(t[lc].sum+t[rc].sum)%mod; } inline void pushdown(ll p) { if(t[p].lazy) { pushnow(lc,t[p].lazy); pushnow(rc,t[p].lazy); t[p].lazy=0; } } inline void build(ll p,ll l,ll r) { t[p].l=l,t[p].r=r; if(l==r) { t[p].sum=a[rk[l]]; return ; } ll bm=l+r>>1; build(lc,l,bm);build(rc,bm+1,r); pushup(p); } inline void update(ll p,ll ql,ll qr,ll v) { if(ql<=t[p].l&&qr>=t[p].r) { pushnow(p,v); return ; } pushdown(p); if(ql<=mid)update(lc,ql,qr,v); if(qr>mid)update(rc,ql,qr,v); pushup(p); } inline ll query(ll p,ll ql,ll qr) { ll ret=0; if(ql<=t[p].l&&qr>=t[p].r) return t[p].sum; pushdown(p); if(ql<=mid)ret=(ret+query(lc,ql,qr))%mod; if(qr>mid)ret=(ret+query(rc,ql,qr))%mod; return ret; } inline void dfs(ll u,ll fa,ll dep) { d[u]=dep;f[u]=fa;siz[u]=1; for(ll i=first[u];i;i=e[i].nxt) { ll v=e[i].v; if(v==fa)continue; dfs(v,u,dep+1); siz[u]+=siz[v]; if(!son[u]||siz[v]>siz[son[u]]) son[u]=v; } } inline void dfs2(ll u,ll t) { top[u]=t;id[u]=++tot;rk[tot]=u; if(son[u]==0)return; dfs2(son[u],t); for(ll i=first[u];i;i=e[i].nxt) { ll v=e[i].v; if(v!=f[u]&&v!=son[u]) dfs2(v,v); } } inline void updtree(ll x,ll y,ll v) { ll fx=top[x],fy=top[y]; while(fx!=fy) { if(d[fx]>d[fy]) { update(1,id[fx],id[x],v); x=f[fx],fx=top[x]; } else { update(1,id[fy],id[y],v); y=f[fy],fy=top[y]; } } if(id[x]<=id[y])update(1,id[x],id[y],v); else update(1,id[y],id[x],v); } inline ll asktree(ll x,ll y) { ll fx=top[x],fy=top[y],ret=0; while(fx!=fy) { if(d[fx]>d[fy]) { ret+=query(1,id[fx],id[x]);ret%=mod; x=f[fx],fx=top[x]; } else { ret+=query(1,id[fy],id[y]);ret%=mod; y=f[fy],fy=top[y]; } } if(id[x]<=id[y])ret+=query(1,id[x],id[y]),ret%=mod; else ret+=query(1,id[y],id[x]),ret%=mod; return ret%mod; } int main() { scanf("%lld%lld%lld%lld",&n,&m,&root,&mod); for(ll i=1;i<=n;i++)scanf("%lld",&a[i]); for(ll i=1;i<n;i++) { ll u,v; scanf("%lld%lld",&u,&v); add(u,v);add(v,u); } dfs(root,0,1);dfs2(root,root);build(1,1,n); for(ll i=1;i<=m;i++) { ll op,x,y,k; scanf("%lld%lld",&op,&x); if(op==1) scanf("%lld%lld",&y,&k),updtree(x,y,k); if(op==2) scanf("%lld",&y),printf("%lld\n",asktree(x,y)); if(op==3) scanf("%lld",&k),update(1,id[x],id[x]+siz[x]-1,k); if(op==4) printf("%lld\n",query(1,id[x],id[x]+siz[x]-1)); } return 0; }
单调队列
#include<bits/stdc++.h> using namespace std; #define N 1000005 int n,t,h,ans; int q[N],L[N],R[N]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d",&L[i],&R[i]); t=h=1;q[t++]=1;ans=1; for(int i=1;i<=n;i++) { while(h<t&&L[q[t-1]]<L[i])t--; q[t++]=i; while(h<t&&L[q[h]]>R[i])h++; ans=max(ans,i-(q[h-1]+1)+1); } printf("%d\n",ans); return 0; }
树状数组
#include<bits/stdc++.h> using namespace std; #define N 500050 int n,m; int a[N],c[N]; inline int lowbit(int x){return x&(-x);} inline void update(int x,int y) { for(;x<=n;x+=lowbit(x)) c[x]+=y; } inline int query(int x) { int ret=0; for(;x;x-=lowbit(x)) ret+=c[x]; return ret; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=m;i++) { int op,x,y,z; scanf("%d",&op); if(op==1) { scanf("%d%d%d",&x,&y,&z); update(x,z),update(y+1,-z); } else { scanf("%d",&x); printf("%d\n",query(x)+a[x]); } } }
二维树状数组
inline int lowbit(int x){return x&(-x);} inline void update(int x,int y,int v) { for(;x<=n;x+=lowbit(x)) for(;y<=n;y+=lowbit(y)) c[x][y]+=v; } inline int query(int x,int y) { int ret=0; for(;x;x-=lowbit(x)) for(;y;y-=lowbit(y)) ret+=c[x][y]; return ret; }
匈牙利算法
#include<bits/stdc++.h> using namespace std; #define N 1010 int n,m,e,ans; int ok[N][N],match[N],ask[N]; inline int find(int x) { for(int i=1;i<=m;i++) { if(ok[x][i]) { if(ask[i])continue; ask[i]=1; if(!match[i]||find(match[i])) { match[i]=x; return 1; } } } return 0; } int main() { scanf("%d%d%d",&n,&m,&e); for(int i=1;i<=e;i++) { int x,y; scanf("%d%d",&x,&y); ok[x][y]=1; } for(int i=1;i<=n;i++) { memset(ask,0,sizeof(ask)); if(find(i))ans++; } printf("%d",ans); return 0; }
字符串hash
luogu3370
背这个long long级别的大质数既不那么容易被卡,时间也很省
#include<bits/stdc++.h> using namespace std; #define N 10010 #define base 131 #define ull unsigned long long #define mod 212370440130137957 int n,ans=0; ull a[N]; char s[N]; ull hash(char s[]) { int len=strlen(s); ull ret=0; for(int i=0;i<len;i++) ret=(ret*base+(ull)s[i])%mod; return ret; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",s); a[i]=hash(s); } sort(a+1,a+1+n); ans=unique(a+1,a+1+n)-(a+1); printf("%d\n",ans); return 0; }
三分
#include<bits/stdc++.h> using namespace std; #define N 20 #define db double #define eps 1e-6 int n; db l,r,lmid,rmid,num[N]; inline db f(db x) { db ret=0; for(int i=n;i>=0;i--) ret+=num[i]*pow(x,i); return ret; } int main() { scanf("%d%lf%lf",&n,&l,&r); for(int i=n;i>=0;i--)scanf("%lf",&num[i]); while(r-l>eps) { lmid=l+(r-l)/3; rmid=r-(r-l)/3; if(f(lmid)<f(rmid))l=lmid; else r=rmid; } printf("%.5lf",r); return 0; }
Manacher
#include<bits/stdc++.h> using namespace std; #define N 30000300 int p[N]; int len,ans=1,mid=1,mx=1; char s[N],pre[N]; void add() { int i=1,j=0;len=strlen(pre+1); s[j]='~';s[++j]='*'; while(i<=len)s[++j]=pre[i++],s[++j]='*'; len=j; } int main() { scanf("%s",pre+1); add(); for(int i=1;i<len;i++) { if(i<mx)p[i]=min(mx-i,p[2*mid-i]); else p[i]=1; while(s[i-p[i]]==s[i+p[i]])p[i]++; if(mx<i+p[i])mx=i+p[i],mid=i; ans=max(ans,p[i]-1); } printf("%d\n",ans); return 0; }
树上差分
#include<bits/stdc++.h> using namespace std; #define N 50050 int n,k,cnt,ans; int c[N],dep[N],first[N],fa[N][20]; struct email { int u,v; int nxt; }e[N*4]; void dfs(int u,int f) { for(int i=1;(1<<i)<=dep[u];i++) fa[u][i]=fa[fa[u][i-1]][i-1]; for(int i=first[u];i;i=e[i].nxt) { int v=e[i].v; if(v==f)continue; fa[v][0]=u; dep[v]=dep[u]+1; dfs(v,u); } } int lca(int x,int y) { if(dep[x]<dep[y]) swap(x,y); int k=dep[x]-dep[y]; for(int i=0;(1<<i)<=k;i++) if(k&(1<<i)) x=fa[x][i]; if(x==y)return x; for(int i=19;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } inline void add(int u,int v) { e[++cnt].nxt=first[u];first[u]=cnt; e[cnt].u=u;e[cnt].v=v; } inline void dfs2(int u,int f) { for(int i=first[u];i;i=e[i].nxt) { int v=e[i].v; if(v==f)continue; dfs2(v,u); c[u]+=c[v]; } ans=max(ans,c[u]); } int main() { scanf("%d%d",&n,&k); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u); } dfs(1,0); for(int i=1;i<=k;i++) { int u,v; scanf("%d%d",&u,&v); c[u]++,c[v]++,c[lca(u,v)]--,c[fa[lca(u,v)][0]]--; } dfs2(1,0); printf("%d\n",ans); return 0; }
分块
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; #define N 100010 #define ll long long ll n,m; char op[3]; ll a[N],sum[N],add[N],L[N],R[N],pos[N]; void update(ll l,ll r,ll v) { ll p=pos[l],q=pos[r]; if(p==q) { for(ll i=l;i<=r;i++)a[i]+=v; sum[p]+=v*(r-l+1); } else { for(ll i=p+1;i<=q-1;i++)add[i]+=v; for(ll i=l;i<=R[p];i++)a[i]+=v; sum[p]+=v*(R[p]-l+1); for(ll i=L[q];i<=r;i++)a[i]+=v; sum[q]+=v*(r-L[q]+1); } } ll query(ll l,ll r) { ll p=pos[l],q=pos[r],ret=0; if(p==q) { for(ll i=l;i<=r;i++)ret+=a[i]; ret+=add[p]*(r-l+1); } else { for(ll i=p+1;i<=q-1;i++)ret+=sum[i]+(R[i]-L[i]+1)*add[i]; for(ll i=l;i<=R[p];i++)ret+=a[i]; ret+=add[p]*(R[p]-l+1); for(ll i=L[q];i<=r;i++)ret+=a[i]; ret+=add[q]*(r-L[q]+1); } return ret; } int main() { scanf("%lld%lld",&n,&m); for(ll i=1;i<=n;i++)scanf("%lld",&a[i]); int t=sqrt(n); for(ll i=1;i<=t;i++)L[i]=(i-1)*t+1,R[i]=i*t; if(R[t]<n)t++,L[t]=R[t-1]+1,R[t]=n; for(ll i=1;i<=t;i++) for(ll j=L[i];j<=R[i];j++) pos[j]=i,sum[i]+=a[j]; while(m--) { ll l,r,d; scanf("%s%lld%lld",op,&l,&r); if(op[0]=='C')scanf("%lld",&d),update(l,r,d); else printf("%lld\n",query(l,r)); } }
完结
“Make my parents proud,and impress the girl I like.”