线性筛
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"bitset"
using namespace std;
const int MAXN=1e7+5;
int n;
int pri[MAXN/10];
int mu[MAXN],phi[MAXN];
bitset<MAXN> b;
int main()
{
scanf("%d",&n);mu[1]=phi[1]=1;
for(int i=2;i<=n;++i){
if(!b[i]) pri[++pri[0]]=i,mu[i]=-1,phi[i]=i-1;
for(int j=1;j<=pri[0]&&pri[j]*i<=n;++j){
b[i*pri[j]]=1;
if(i%pri[j]) mu[i*pri[j]]=-mu[i],phi[i*pri[j]]=phi[i]*phi[pri[j]];
else{mu[i*pri[j]]=0,phi[i*pri[j]]=pri[j]*phi[i];break;}
}
}return 0;
}
线性求逆元
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=20000528;
int n,p;
int inv[MAXN];
int main()
{
scanf("%d%d",&n,&p);inv[1]=1;
for(int i=2;i<=n;++i) inv[i]=(long long)(p-(p/i))*inv[p%i]%p;
for(int i=1;i<=n;++i) printf("%d
",inv[i]);
return 0;
}
三分法
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const double eps=1e-8;
const double ct=1.0/3;
int n;
double L,R;
double a[14];
double calc(double x)
{
double s=a[0];
for(int i=1;i<=n;++i) s=s*x+a[i];
return s;
}
int main()
{
scanf("%d%lf%lf",&n,&L,&R);
for(int i=0;i<=n;++i) scanf("%lf",&a[i]);
double l=L,r=R;
while(r-l>eps){
double mid1=l+(r-l)*ct,mid2=r-(r-l)*ct;
if(calc(mid1)>calc(mid2)) r=mid2;
else l=mid1;
}printf("%.5lf",l);
return 0;
}
线段树
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1<<18;
int n,m,p;
int a[MAXN];
int tree[MAXN],tag[2][MAXN];
void build(int k,int l,int r)
{
tag[0][k]=0;tag[1][k]=1;
if(l==r){
tree[k]=a[l];
return;
}int i=k<<1,mid=l+r>>1;
build(i,l,mid);build(i|1,mid+1,r);
tree[k]=(tree[i]+tree[i|1])%p;
}
void init()
{
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
build(1,1,n);return;
}
void pd(int k,int l,int r)
{
if(l==r||(!tag[0][k]&&tag[1][k]==1)) return;
int i=k<<1,mid=l+r>>1;
tag[0][i]=((long long)tag[0][i]*tag[1][k]%p+tag[0][k])%p;
tag[0][i|1]=((long long)tag[0][i|1]*tag[1][k]%p+tag[0][k])%p;
tag[1][i]=(long long)tag[1][i]*tag[1][k]%p;
tag[1][i|1]=(long long)tag[1][i|1]*tag[1][k]%p;
tree[i]=((long long)tree[i]*tag[1][k]%p+(long long)tag[0][k]*(mid-l+1)%p)%p;
tree[i|1]=((long long)tree[i|1]*tag[1][k]%p+(long long)tag[0][k]*(r-mid)%p)%p;
tag[0][k]=0;tag[1][k]=1;return;
}
void ctag(int k,int l,int r,int le,int ri,int x,bool kd)
{
pd(k,l,r);
if(le<=l&&r<=ri){
tag[kd][k]=x;
if(kd) tree[k]=(long long)tree[k]*x%p;
else tree[k]=(tree[k]+(long long)x*(r-l+1))%p;
return;
}int i=k<<1,mid=l+r>>1;
if(le<=mid) ctag(i,l,mid,le,ri,x,kd);
if(mid<ri) ctag(i|1,mid+1,r,le,ri,x,kd);
tree[k]=(tree[i]+tree[i|1])%p;
}
int cask(int k,int l,int r,int le,int ri)
{
pd(k,l,r);
if(le<=l&&r<=ri) return tree[k];
int sum=0,i=k<<1,mid=l+r>>1;
if(le<=mid) sum=cask(i,l,mid,le,ri);
if(mid<ri) sum=((long long)sum+cask(i|1,mid+1,r,le,ri))%p;
return sum;
}
void solve()
{
while(m--){
int k,l,r,x;
scanf("%d",&k);
if(k!=3) scanf("%d%d%d",&l,&r,&x),ctag(1,1,n,l,r,x,k&1);
else scanf("%d%d",&l,&r),printf("%d
",cask(1,1,n,l,r));
}return;
}
main()
{
init();
solve();
return 0;
}
树链剖分LCA
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1<<19;
int n,m,root,np;
int h[MAXN],top[MAXN],dep[MAXN];
int f[MAXN],sn[MAXN],siz[MAXN];
struct rpg{
int li,nx;
}a[MAXN<<1];
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||'9'<ch) ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return x;
}
inline void add(int ls,int nx){a[++np]=(rpg){h[ls],nx};h[ls]=np;}
void init()
{
n=read(),m=read(),root=read();
for(int i=1;i<n;++i){
int x=read(),y=read();
add(x,y);add(y,x);
}return;
}
void dfs1(int x,int tp,int fa)
{
f[x]=fa;
dep[x]=tp;
siz[x]=1;
int hwysn=0;
for(int i=h[x];i;i=a[i].li){
if(a[i].nx!=fa){
dfs1(a[i].nx,tp+1,x);
siz[x]+=siz[a[i].nx];
if(siz[a[i].nx]>hwysn){
hwysn=siz[a[i].nx];
sn[x]=a[i].nx;
}
}
}return;
}
void dfs2(int x,int tpx)
{
top[x]=tpx;
if(sn[x]) dfs2(sn[x],tpx);
for(int i=h[x];i;i=a[i].li){
if(a[i].nx!=f[x]&&a[i].nx!=sn[x]){
dfs2(a[i].nx,a[i].nx);
}
}return;
}
int LCA(int x,int y)
{
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=f[top[x]];
}return dep[x]<dep[y]?x:y;
}
void solve()
{
while(m--){
int x=read(),y=read();
printf("%d
",LCA(x,y));
}return;
}
int main()
{
init();
dfs1(root,1,root);
dfs2(root,root);
solve();
return 0;
}
树链剖分
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1<<17;
int n,m,root,MOD,np;
int siz[MAXN],sn[MAXN],f[MAXN],id[MAXN],num[MAXN];
int ren[MAXN],top[MAXN],dep[MAXN],h[MAXN];
int tree[MAXN<<1],pls[MAXN<<1];
struct rpg{
int li,nx;
}a[MAXN<<1];
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||'9'<ch) ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return x;
}
inline void add(int ls,int nx)
{
a[++np]=(rpg){h[ls],nx};h[ls]=np;
a[++np]=(rpg){h[nx],ls};h[nx]=np;
}
void dfs1(int x,int tp,int fa)
{
dep[x]=tp;f[x]=fa;siz[x]=1;
int hwysn=0;
for(int i=h[x];i;i=a[i].li){
if(a[i].nx!=fa){
dfs1(a[i].nx,tp+1,x);
siz[x]+=siz[a[i].nx];
if(siz[a[i].nx]>hwysn){
hwysn=siz[a[i].nx];
sn[x]=a[i].nx;
}
}
}return;
}
void dfs2(int x,int tpx)
{
top[x]=tpx;id[x]=++id[0];ren[id[x]]=num[x];
if(sn[x]) dfs2(sn[x],tpx);
for(int i=h[x];i;i=a[i].li){
if(a[i].nx!=f[x]&&a[i].nx!=sn[x]){
dfs2(a[i].nx,a[i].nx);
}
}return;
}
void build(int k,int l,int r)
{
if(l==r){
tree[k]=ren[l];
return;
}int i=k<<1,mid=l+r>>1;
build(i,l,mid);build(i|1,mid+1,r);
tree[k]=(tree[i]+tree[i|1])%MOD;
}
void init()
{
n=read(),m=read(),root=read(),MOD=read();
for(int i=1;i<=n;++i) num[i]=read();
for(int i=1;i<n;++i) add(read(),read());
dfs1(root,1,root);dfs2(root,root);
build(1,1,n);
return;
}
void pd(int k,int l,int r)
{
if(l==r||!pls[k]) return;
int i=k<<1,mid=l+r>>1;
pls[i]=(pls[i]+pls[k])%MOD;
pls[i|1]=(pls[i|1]+pls[k])%MOD;
tree[i]=(tree[i]+pls[k]*(mid-l+1))%MOD;
tree[i|1]=(tree[i|1]+pls[k]*(r-mid))%MOD;
pls[k]=0;return;
}
void cpls(int k,int l,int r,int le,int ri,int x)
{
pd(k,l,r);
if(le<=l&&r<=ri){
pls[k]=x;
tree[k]=(tree[k]+x*(r-l+1))%MOD;
return;
}int i=k<<1,mid=l+r>>1;
if(le<=mid) cpls(i,l,mid,le,ri,x);
if(mid<ri) cpls(i|1,mid+1,r,le,ri,x);
tree[k]=(tree[i]+tree[i|1])%MOD;
}
void ccpls(int x,int y,int z)
{
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
cpls(1,1,n,id[top[x]],id[x],z);
x=f[top[x]];
}if(dep[x]>dep[y]) swap(x,y);
cpls(1,1,n,id[x],id[y],z);
return;
}
int cask(int k,int l,int r,int le,int ri)
{
pd(k,l,r);
if(le<=l&&r<=ri) return tree[k];
int i=k<<1,mid=l+r>>1,sum=0;
if(le<=mid) sum=cask(i,l,mid,le,ri);
if(mid<ri) sum=(sum+cask(i|1,mid+1,r,le,ri))%MOD;
return sum;
}
int ccask(int x,int y)
{
int sum=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
sum=(sum+cask(1,1,n,id[top[x]],id[x]))%MOD;
x=f[top[x]];
}if(dep[x]>dep[y]) swap(x,y);
sum=(sum+cask(1,1,n,id[x],id[y]))%MOD;
return sum;
}
void solve()
{
while(m--){
int k=read();
if(k==1){int x=read(),y=read(),z=read();ccpls(x,y,z);}
else if(k==2){int x=read(),y=read();printf("%d
",ccask(x,y));}
else if(k==3){int x=read(),z=read();cpls(1,1,n,id[x],id[x]+siz[x]-1,z);}
else {int x=read();printf("%d
",cask(1,1,n,id[x],id[x]+siz[x]-1));}
}return;
}
main()
{
init();
solve();
return 0;
}
矩阵快速幂
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=105;
const int MOD=1e9+7;
int n;
long long k;
struct matrix{
long long val[MAXN][MAXN];
void reset(){memset(val,0,sizeof(val));}
matrix Mmul(matrix a,matrix b)
{
matrix c;c.reset();
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
for(int k=1;k<=n;++k){
c.val[i][j]=(c.val[i][j]+a.val[i][k]*b.val[k][j])%MOD;
}
}
}return c;
}
matrix MFpw(matrix a,long long b,int siz)
{
matrix x;x.reset();
for(int i=1;i<=siz;++i) x.val[i][i]=1;
while(b){
if(b&1) x=Mmul(x,a);
b>>=1;a=Mmul(a,a);
}return x;
}
void write()
{
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
printf("%lld ",val[i][j]);
}puts("");
}return;
}
}a;
int main()
{
scanf("%d%lld",&n,&k);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
scanf("%lld",&a.val[i][j]);
}
}a=a.MFpw(a,k,n);
a.write();
return 0;
}
可持久化线段树
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1<<18;
int n,m,cnt;
int rev[MAXN],rt[MAXN];
int val[MAXN<<5],L[MAXN<<5],R[MAXN<<5];
struct rpg{
int a,b,id;
}v[MAXN];
bool cmp1(rpg a,rpg b){return a.a<b.a;}
bool cmp2(rpg a,rpg b){return a.id<b.id;}
void ins(int rid,int id,int x,int l,int r)
{
int mid=l+r>>1;
val[id]=val[rid]+1;
if(l==r) return;
++cnt;
if(x<=mid) L[id]=cnt,R[id]=R[rid],ins(L[rid],cnt,x,l,mid);
else R[id]=cnt,L[id]=L[rid],ins(R[rid],cnt,x,mid+1,r);
return;
}
int query(int lid,int rid,int x,int l,int r)
{
if(l==r) return l;
int mid=l+r>>1;int ct=val[L[rid]]-val[L[lid]];
if(x<=ct) return query(L[lid],L[rid],x,l,mid);
return query(R[lid],R[rid],x-ct,mid+1,r);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&v[i].a),v[i].id=i;
sort(v+1,v+n+1,cmp1);
for(int i=1;i<=n;++i) v[i].b=i,rev[i]=v[i].a;
sort(v+1,v+n+1,cmp2);
for(int i=1;i<=n;++i) ++cnt,rt[i]=cnt,ins(rt[i-1],rt[i],v[i].b,1,n);
while(m--){
int l,r,c;scanf("%d%d%d",&l,&r,&c);
printf("%d
",rev[query(rt[l-1],rt[r],c,1,n)]);
}return 0;
}
树状数组(单修区查)
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=5e5+5;
int n,m;
int btre[MAXN];
inline int read()
{
int x=0;bool f=0;char ch=getchar();
while(ch<'0'||'9'<ch){if(ch=='-') f=1;ch=getchar();}
while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return f?-x:x;
}
inline void ins(int k,int x){while(k<=n) btre[k]+=x,k+=k&-k;}
inline int ask(int k){int sum=0;while(k) sum+=btre[k],k-=k&-k;return sum;}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;++i){int x=read();ins(i,x);}
while(m--){
int k=read();
if(k==1){int x=read(),y=read();ins(x,y);}
else{int l=read(),r=read();printf("%d
",ask(r)-ask(l-1));}
}return 0;
}
二维树状数组(单修区查)
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1e5+5;
int n,m;
long long BIT[2][MAXN];
void cadd(int x,long long v)
{
for(int i=x;i<=n;i+=i&(-i)){
BIT[0][i]+=v;
BIT[1][i]+=v*(x-1);
}return;
}
long long query(int x)
{
long long sum=0;
for(int i=x;i;i-=i&(-i)){
sum+=BIT[0][i]*x;
sum-=BIT[1][i];
}return sum;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
long long x;scanf("%lld",&x);
cadd(i,x);cadd(i+1,-x);
}while(m--){
int p,l,r;
scanf("%d%d%d",&p,&l,&r);
if(p==1){long long x;scanf("%lld",&x);cadd(l,x);cadd(r+1,-x);}
else printf("%lld
",query(r)-query(l-1));
}return 0;
}
树状数组(区修区查)
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1<<11|1;
int n,m,q;
long long bit[4][MAXN][MAXN];
void cadd(int x,int y,long long v)
{
for(int i=x;i<=n;i+=i&(-i)){
for(int j=y;j<=m;j+=j&(-j)){
bit[0][i][j]+=v;
bit[1][i][j]+=v*(x-1);
bit[2][i][j]+=v*(y-1);
bit[3][i][j]+=v*(x-1)*(y-1);
}
}return;
}
long long cask(int x,int y)
{
long long sum=0;
for(int i=x;i;i&=i-1){
for(int j=y;j;j&=j-1){
sum+=bit[0][i][j]*x*y;
sum-=bit[1][i][j]*y;
sum-=bit[2][i][j]*x;
sum+=bit[3][i][j];
}
}return sum;
}
void cad(int sx,int sy,int tx,int ty,long long v)
{
cadd(sx,sy,v);
cadd(sx,ty+1,-v);
cadd(tx+1,sy,-v);
cadd(tx+1,ty+1,v);
return;
}
long long query(int sx,int sy,int tx,int ty)
{
return cask(tx,ty)-cask(tx,sy-1)-cask(sx-1,ty)+cask(sx-1,sy-1);
}
int main()
{
scanf("%d%d",&n,&m);
while(scanf("%d",&q)==1){
int sx,sy,tx,ty;
scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
if(q==1){long long x;scanf("%lld",&x);cad(sx,sy,tx,ty,x);}
else printf("%lld
",query(sx,sy,tx,ty));
}return 0;
}
EXGCD
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
int x,y,n,m,k;
int exgcd(int a,int b,int &x,int &y)
{
if(!b){x=1;return a;}
int c=exgcd(b,a%b,y,x);
y-=a/b*x;return c;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int c=exgcd(n,m,x,y);
if(k%c) puts("-1");
else printf("%d %d",x*k/c,y*k/c);
return 0;
}
EXCRT
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
int n;
long long a,b,ans,asmd;
long long Fml(long long a,long long b,long long MOD)
{
long long x=0;
while(b){
if(b&1) x=(x+a)%MOD;
b>>=1;a=(a<<1)%MOD;
}return x;
}
long long Exgcd(long long a,long long b,long long &x,long long &y)
{
if(!b){x=1,y=0;return a;}
long long c=Exgcd(b,a%b,y,x);
y-=a/b*x;return c;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%lld%lld",&a,&b);
if(i==1){ans=b,asmd=a;continue;}
long long x,y,nw=((b-ans)%a+a)%a;
long long c=Exgcd(asmd,a,x,y);
nw/=c;x=Fml(x,nw,a/c);
ans+=x*asmd;asmd*=a/c;
ans=(ans%asmd+asmd)%asmd;
}printf("%lld
",ans);
return 0;
}
Lucas
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1e5+5;
int T,n,m,MOD;
int fac[MAXN],inv[MAXN];
int Lucas(int m,int n)
{
if(n<m) return 0;
if(n<=MOD) return (int)((long long)fac[n]*inv[fac[m]]*inv[fac[n-m]]%MOD);
return (int)((long long)Lucas(m%MOD,n%MOD)*Lucas(m/MOD,n/MOD)%MOD);
}
int main()
{
scanf("%d",&T);fac[0]=inv[1]=1;
while(T--){
scanf("%d%d%d",&n,&m,&MOD);
for(int i=1;i<MOD;++i) fac[i]=(long long)fac[i-1]*i%MOD;
for(int i=2;i<MOD;++i) inv[i]=(long long)(MOD-(MOD/i))*inv[MOD%i]%MOD;
printf("%d
",Lucas(m,n+m));
}return 0;
}
SA
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1e6+5;
char ch[MAXN];
int ln,maxn;
int SA[MAXN],rnk[MAXN],bnk[MAXN],id[MAXN];
void shel()
{
memset(bnk,0,sizeof(bnk));
for(int i=1;i<=ln;++i) ++bnk[rnk[i]];
for(int i=1;i<=maxn;++i) bnk[i]+=bnk[i-1];
for(int i=ln;i;--i) SA[bnk[rnk[id[i]]]--]=id[i];
return;
}
int main()
{
scanf("%s",ch+1);ln=strlen(ch+1);
for(int i=1;i<=ln;++i) rnk[i]=ch[i],id[i]=i,maxn=max(maxn,rnk[i]);
shel();
for(int k=1;k<ln;k<<=1){
for(int i=1;i<=k;++i) id[i]=ln-k+i;
int ct=k;for(int i=1;i<=ln;++i) if(SA[i]>k) id[++ct]=SA[i]-k;
shel();swap(id,rnk);rnk[SA[1]]=1;
for(int i=2;i<=ln;++i) rnk[SA[i]]=(id[SA[i]]==id[SA[i-1]]&&id[SA[i]+k]==id[SA[i-1]+k])?rnk[SA[i-1]]:rnk[SA[i-1]]+1;
if(rnk[SA[ln]]==ln) break;
maxn=rnk[SA[ln]];
}for(int i=1;i<=ln;++i) printf("%d ",SA[i]);
return 0;
}
Kruskal
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=5005;
const int MAXM=2e5+5;
int n,m,sum;
int f[MAXN];
struct rpg{
int ls,nx,ln;
}a[MAXM];
bool cmp(rpg a,rpg b){return a.ln<b.ln;}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void un(int a,int b){if(find(a)!=find(b)) f[find(a)]=find(b);}
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",&a[i].ls,&a[i].nx,&a[i].ln);
sort(a+1,a+m+1,cmp);int cnt=0;
for(int i=1;i<=m;++i){
if(find(a[i].ls)!=find(a[i].nx)){
un(a[i].ls,a[i].nx);sum+=a[i].ln;++cnt;
}if(cnt==n-1){printf("%d
",sum);return 0;}
}puts("orz");
return 0;
}
Dijkstra
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"bitset"
using namespace std;
const int MAXN=1e5+5;
const int INF=2e9;
int n,m,s,np;
int hp[MAXN],h[MAXN],ln[MAXN],id[MAXN];
struct rpg{
int li,nx,ln;
}a[MAXN<<1];
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||'9'<ch) ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
return x;
}
inline void add(int ls,int nx,int ln){a[++np]=(rpg){h[ls],nx,ln};h[ls]=np;}
void up(int x)
{
for(int i=x,j=x>>1;j;i=j,j>>=1){
if(ln[hp[i]]<ln[hp[j]]) swap(hp[i],hp[j]),swap(id[hp[i]],id[hp[j]]);
else break;
}return;
}
void ins(int x){hp[++hp[0]]=x;id[x]=hp[0];up(hp[0]);}
void pop()
{
id[hp[1]]=0;id[hp[hp[0]]]=1;
hp[1]=hp[hp[0]--];
for(int i=1,j=2;j<=hp[0];i=j,j<<=1){
if(j<hp[0]&&ln[hp[j+1]]<ln[hp[j]]) ++j;
if(ln[hp[i]]>ln[hp[j]]) swap(hp[i],hp[j]),swap(id[hp[i]],id[hp[j]]);
else break;
}return;
}
void dijkstra()
{
for(int i=1;i<=n;++i) ln[i]=INF;
ln[s]=0;ins(s);
while(hp[0]){
int nw=hp[1];pop();
for(int i=h[nw];i;i=a[i].li){
if(ln[a[i].nx]>ln[nw]+a[i].ln){
ln[a[i].nx]=ln[nw]+a[i].ln;
if(!id[a[i].nx]) ins(a[i].nx);
else up(id[a[i].nx]);
}
}
}return;
}
int main()
{
n=read(),m=read(),s=read();
for(int i=1;i<=m;++i){
int x=read(),y=read(),z=read();
add(x,y,z);
}dijkstra();
for(int i=1;i<=n;++i) printf("%d ",ln[i]);
return 0;
}
高精度(压9位)
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1e4+5;
const int MOD=1e9;
const int siz=9;
char ch[2][MAXN];
long long num[6][MAXN];
void slv(int id)
{
int ln=strlen(ch[id]);
for(int i=ln-1;i+1>=siz;i-=siz){
++num[id][0];
for(int j=i-siz+1;j<=i;++j) num[id][num[id][0]]=(num[id][num[id][0]]<<3)+(num[id][num[id][0]]<<1)+(ch[id][j]^'0');
}if(ln%siz){
++num[id][0];
for(int i=0;i<ln%siz;++i) num[id][num[id][0]]=(num[id][num[id][0]]<<3)+(num[id][num[id][0]]<<1)+(ch[id][i]^'0');
}num[id][0]=max(num[id][0],1ll);
return;
}
void clear(int id)
{
for(int i=num[id][0];i;--i) num[id][i]=0;
num[id][0]=1;return;
}
void write(int id)
{
printf("%lld",num[id][num[id][0]]);
for(int i=num[id][0]-1;i;--i) printf("%09lld",num[id][i]);
puts("");return;
}
void init()
{
scanf("%s%s",ch[0],ch[1]);
slv(0);slv(1);return;
}
int cmp(int id1,int id2)
{
if(num[id1][0]>num[id2][0]) return 1;
if(num[id1][0]<num[id2][0]) return -1;
for(int i=num[id1][0];i;--i){
if(num[id1][i]>num[id2][i]) return 1;
if(num[id1][i]<num[id2][i]) return -1;
}return 0;
}
void cpy(int id1,int id2)
{
clear(id1);
for(int i=0;i<=num[id2][0];++i) num[id1][i]=num[id2][i];
return;
}
void ly(int id)
{
for(int i=num[id][0];i;--i){
num[id][i]<<=1;
if(num[id][i]>=MOD) ++num[id][i+1],num[id][i]-=MOD;
}if(num[id][num[id][0]+1]) ++num[id][0];
return;
}
void ry(int id)
{
for(int i=1;i<=num[id][0];++i){
if(num[id][i]&1&&i>1) num[id][i-1]+=MOD>>1;
num[id][i]>>=1;
}if(!num[id][num[id][0]]&&num[id][0]>1) --num[id][0];
return;
}
void pls(int id1,int id2,int id3)
{
num[id3][0]=max(num[id1][0],num[id2][0])+1;
for(int i=1;i<=num[id3][0];++i){
num[id3][i]+=num[id1][i]+num[id2][i];
if(num[id3][i]>=MOD) ++num[id3][i+1],num[id3][i]-=MOD;
}if(!num[id3][num[id3][0]]&&num[id3][0]>1) --num[id3][0];
return;
}
void mnu(int id1,int id2,int id3)
{
num[id3][0]=max(num[id1][0],num[id2][0]);
if(cmp(id1,id2)==-1) putchar('-'),swap(id1,id2);
for(int i=1;i<=num[id3][0];++i){
num[id3][i]+=num[id1][i]-num[id2][i];
if(num[id3][i]<0) --num[id3][i+1],num[id3][i]+=MOD;
}while(!num[id3][num[id3][0]]&&num[id3][0]>1) --num[id3][0];
return;
}
void mul(int id1,int id2,int id3)
{
num[id3][0]=num[id1][0]+num[id2][0];
for(int i=1;i<=num[id1][0];++i){
for(int j=1;j<=num[id2][0];++j){
num[id3][i+j-1]+=num[id1][i]*num[id2][j];
if(num[id3][i+j-1]>=MOD) num[id3][i+j]+=num[id3][i+j-1]/MOD,num[id3][i+j-1]%=MOD;
}
}while(!num[id3][num[id3][0]]&&num[id3][0]>1) --num[id3][0];
return;
}
void div(int id1,int id2,int id3,int id4,int ck,int rk)
{
num[ck][0]=num[ck][1]=1;
while(cmp(id1,id2)>0){ly(id2),ly(ck);}
while(num[ck][0]>1||num[ck][1]){
if(cmp(id1,id2)>=0){
clear(id4);mnu(id1,id2,id4);cpy(id1,id4);
clear(rk);pls(id3,ck,rk);cpy(id3,rk);
}ry(id2),ry(ck);
}return;
}
int main()
{
init();
pls(0,1,2);write(2);clear(2);
mnu(0,1,2);write(2);clear(2);
mul(0,1,2);write(2);clear(2);clear(3);
div(0,1,2,3,4,5);write(2);write(0);
return 0;
}
Gauss
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=105;
const double eps=1e-8;
int n;
struct matrix{
double val[MAXN][MAXN];
bool fl1,fl2;
double fabs(double x){return x>-eps?x:-x;}
void Gauss()
{
for(int i=1;i<=n;++i){
int p=i;
for(int j=i+1;j<=n;++j) if(fabs(val[j][i])>fabs(val[p][i])) p=j;
swap(val[i],val[p]);if(fabs(val[i][i])<eps) continue;
double tmp=val[i][i];
for(int j=1;j<=n+1;++j) val[i][j]/=tmp;
for(int j=1;j<=n;++j){
if(i!=j){
double tmp=val[j][i];
for(int k=1;k<=n+1;++k) val[j][k]-=val[i][k]*tmp;
}
}
}for(int i=1;i<=n;++i){
int cnt=1;while(fabs(val[i][cnt])<eps&&cnt<=n+1) ++cnt;
if(cnt==n+1) fl1=1;else if(cnt>n+1) fl2=1;
}return;
}
void write()
{
if(fl1){puts("-1");return;}
if(fl2){puts("0");return;}
for(int i=1;i<=n;++i){
if(fabs(val[i][n+1])<eps) printf("x%d=0
",i);
else printf("x%d=%.2lf
",i,val[i][n+1]);
}return;
}
}a;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i){
for(int j=1;j<=n+1;++j){
scanf("%lf",&a.val[i][j]);
}
}a.Gauss();
a.write();
return 0;
}
ST
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1e5+5;
int n,m;
int ST[17][MAXN];
int log[MAXN];
int query(int l,int r){return max(ST[log[r-l+1]][l],ST[log[r-l+1]][r-(1<<log[r-l+1])+1]);}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&ST[0][i]);
for(int i=1;i<=n;++i){
log[i]=log[i-1];
if(i>>log[i]+1) ++log[i];
}for(int i=1;i<=log[n];++i){
for(int j=1;j<=n-(1<<i)+1;++j){
ST[i][j]=max(ST[i-1][j],ST[i-1][j+(1<<i-1)]);
}
}while(m--){
int x,y;scanf("%d%d",&x,&y);
printf("%d
",query(x,y));
}return 0;
}
Trie
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXL=505;
const int MAXN=2005;
int n,m,siz;
char ch[MAXN];
struct rpg{
int sn[80];
int vis;
}Trie[MAXN*MAXL];
void ins(char *ch)
{
int nw=0,ln=strlen(ch);
for(int i=0;i<ln;++i){
if(!Trie[nw].sn[ch[i]-'0']) Trie[nw].sn[ch[i]-'0']=++siz;
nw=Trie[nw].sn[ch[i]-'0'];
}++Trie[nw].vis;
return;
}
int calc(char *ch)
{
int nw=0,ln=strlen(ch);
for(int i=0;i<ln;++i){
if(!Trie[nw].sn[ch[i]-'0']) return 0;
nw=Trie[nw].sn[ch[i]-'0'];
}return Trie[nw].vis;
}
int main()
{
scanf("%d%d",&n,&m);
while(n--){scanf("%s",ch);ins(ch);}
while(m--){scanf("%s",ch);printf("%d
",calc(ch));}
return 0;
}
缩点+DAG上DP
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"bitset"
using namespace std;
const int MAXN=1e4+5;
const int MAXM=1e5+5;
int n,m,np,ans;
int h[MAXN],siz[MAXN],clr[MAXN],rsiz[MAXN];
int stk[MAXN],low[MAXN],dfn[MAXN],q[MAXN],idg[MAXN];
int x[MAXM],y[MAXM];
bitset<MAXN> vis;
struct rpg{
int li,nx;
}a[MAXM];
void add(int ls,int nx){a[++np]=(rpg){h[ls],nx};h[ls]=np;}
void Tarjan(int x)
{
low[x]=dfn[x]=++dfn[0];
stk[++stk[0]]=x;vis[x]=1;
for(int i=h[x];i;i=a[i].li){
if(!dfn[a[i].nx]) Tarjan(a[i].nx),low[x]=min(low[x],low[a[i].nx]);
else if(vis[a[i].nx]) low[x]=min(low[x],dfn[a[i].nx]);
}if(dfn[x]==low[x]){
clr[x]=++clr[0];vis[x]=0;rsiz[clr[x]]=siz[x];
while(stk[stk[0]]!=x){
clr[stk[stk[0]]]=clr[x];
rsiz[clr[x]]+=siz[stk[stk[0]]];
vis[stk[stk[0]--]]=0;
}--stk[0];
}return;
}
void Torp()
{
int hd=1,tl=0;
for(int i=1;i<=clr[0];++i) if(!idg[i]) q[++tl]=i,siz[i]=rsiz[i];
while(hd<=tl){
int nw=q[hd++];ans=max(ans,siz[nw]);
for(int i=h[nw];i;i=a[i].li){
siz[a[i].nx]=max(siz[a[i].nx],siz[nw]+rsiz[a[i].nx]);
if(!--idg[a[i].nx]) q[++tl]=a[i].nx;
}
}return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&siz[i]);
for(int i=1;i<=m;++i){scanf("%d%d",&x[i],&y[i]);add(x[i],y[i]);}
for(int i=1;i<=n;++i) if(!clr[i]) Tarjan(i);
memset(h,0,sizeof(h));np=0;memset(siz,0,sizeof(siz));
for(int i=1;i<=m;++i) if(clr[x[i]]!=clr[y[i]]) add(clr[x[i]],clr[y[i]]),++idg[clr[y[i]]];
Torp();printf("%d
",ans);
return 0;
}
割点
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"bitset"
using namespace std;
const int MAXN=1e5+5;
int n,m,np,cnt;
int h[MAXN],stk[MAXN],dfn[MAXN],low[MAXN],ans[MAXN];
bitset<MAXN> cut;
struct rpg{
int li,nx;
}a[MAXN<<1];
void add(int ls,int nx)
{
a[++np]=(rpg){h[ls],nx};h[ls]=np;
a[++np]=(rpg){h[nx],ls};h[nx]=np;
}
void Tarjan(int x,int root)
{
low[x]=dfn[x]=++dfn[0];
for(int i=h[x];i;i=a[i].li){
if(!dfn[a[i].nx]){
Tarjan(a[i].nx,root);low[x]=min(low[x],low[a[i].nx]);
if(low[a[i].nx]>=dfn[x]&&x!=root) cut[x]=1;
if(x==root) ++cnt;
}else low[x]=min(low[x],dfn[a[i].nx]);
}if(x==root&&cnt>=2) cut[x]=1;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){int x,y;scanf("%d%d",&x,&y);add(x,y);}
for(int i=1;i<=n;++i) if(!dfn[i]) cnt=0,Tarjan(i,i);
for(int i=1;i<=n;++i) if(cut[i]) ans[++ans[0]]=i;printf("%d
",ans[0]);
sort(ans+1,ans+ans[0]+1);for(int i=1;i<=ans[0];++i) printf("%d ",ans[i]);
return 0;
}
二维凸包
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"cmath"
using namespace std;
const int MAXN=10005;
int n;
int stk[2][MAXN];
double ans;
struct rpg{
double x,y;
}a[MAXN];
bool cmp(rpg a,rpg b){return a.x==b.x?a.y<b.y:a.x<b.x;}
bool check(int i,int j,int k){return (a[k].y-a[i].y)*(a[j].x-a[i].x)<(a[j].y-a[i].y)*(a[k].x-a[i].x);}
double ln(int i,int j){return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));}
int main()
{
scanf("%d",&n);for(int i=1;i<=n;++i) scanf("%lf%lf",&a[i].x,&a[i].y);
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;++i){
while(stk[0][0]>1&&check(stk[0][stk[0][0]-1],stk[0][stk[0][0]],i)) --stk[0][0];
stk[0][++stk[0][0]]=i;
}for(int i=1;i<=n;++i){
while(stk[1][0]>1&&!check(stk[1][stk[1][0]-1],stk[1][stk[1][0]],i)) --stk[1][0];
stk[1][++stk[1][0]]=i;
}for(int i=1;i<stk[0][0];++i) ans+=ln(stk[0][i],stk[0][i+1]);
for(int i=1;i<stk[1][0];++i) ans+=ln(stk[1][i],stk[1][i+1]);
printf("%.2lf
",ans);
return 0;
}
AC自动机
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1e6+5;
const int siz=26;
int n,cnt;
long long ans;
int q[MAXN];
char ch[MAXN];
struct Trie{
int vis,fail;
int sn[siz];
}T[MAXN];
void ins(char *ch)
{
int nw=0,ln=strlen(ch+1);
for(int i=1;i<=ln;++i){
if(!T[nw].sn[ch[i]-'a']) T[nw].sn[ch[i]-'a']=++cnt;
nw=T[nw].sn[ch[i]-'a'];
}++T[nw].vis;
return;
}
void Getfail()
{
int hd=1,tl=0;
for(int i=0;i<26;++i) if(T[0].sn[i]) q[++tl]=T[0].sn[i];
while(hd<=tl){
int nw=q[hd++];
for(int i=0;i<26;++i){
if(T[nw].sn[i]){
T[T[nw].sn[i]].fail=T[T[nw].fail].sn[i];
q[++tl]=T[nw].sn[i];
}else T[nw].sn[i]=T[T[nw].fail].sn[i];
}
}return;
}
void query(char *ch)
{
int ln=strlen(ch+1),nw=0;
for(int i=1;i<=ln;++i){
nw=T[nw].sn[ch[i]-'a'];
for(int j=nw;j&&T[j].vis!=-1;j=T[j].fail) ans+=T[j].vis,T[j].vis=-1;
}return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%s",ch+1),ins(ch);
Getfail();scanf("%s",ch+1);
query(ch);printf("%lld
",ans);
return 0;
}
LCT
bool nrt(int x) {return sn[0][f[x]]==x||sn[1][x]==x;}
void pushup(int x);
void pushtag(int x) {swap(sn[0][x],sn[1][x]);tag[x]^=1;}
void pushdown(int x) {if(tag[x]) pushtag(sn[0][x]),pushtag(sn[1][x]),tag[x]=0;}
void psd(int x) {if(nrt(x)) psd(f[x]);pushdown(x);}
bool gsn(int x) {return sn[1][f[x]]==x;}
void ro(int x){
int y=f[x],z=f[y],k=gsn(x),w=sn[!k][x];
if(nrt(y)) sn[gsn(y)][z]=x;sn[!k][x]=y,sn[k][y]=w;
if(w) f[w]=y;f[y]=x,f[x]=z,pushup(y);
return;
}
void splay(int x) {psd(x);while(nrt(x)){if(nrt(f[x])) ro(gsn(x)^gsn(f[x])?x:f[x]);ro(x);}pushup(x);}
void acs(int x) {for(int y=0;x;x=f[y=x]) splay(x),sn[1][x]=y,pushup(x);}
void mkrt(int x) {acs(x),splay(x),pushtag(x);}
int fdrt(int x) {acs(x),splay(x);while(sn[0][x]) pushdown(x),x=sn[0][x];splay(x);return x;}
void split(int x,int y) {mkrt(x),acs(y),splay(y);}
void link(int x,int y) {mkrt(x);if(fdrt(y)!=x) f[x]=y;}
void cut(int x,int y) {mkrt(x);if(fdrt(y)==x&&f[y]==x&&!sn[0][y]) f[y]=sn[1][x]=0,pushup(x);}