读入优化 - 慢
#define int long long int read(){ int x=0; char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+ch-48,ch=getchar(); return x; } #undef int
FastIO
namespace IO{ const int Len=1<<21; char Ibuf[Len+1],*Is=Ibuf,*It=Ibuf; char gc(){ if (Is==It){ It=(Is=Ibuf)+fread(Ibuf,1,Len,stdin); if (Is==It) return EOF; } return *Is++; } int read(){ int x=0,f=0; char ch=gc(); while (!isdigit(ch)) f|=ch=='-',ch=gc(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc(); return f?-x:x; } char Obuf[Len+1],*Ot=Obuf; void pc(char ch){ if (Ot==Obuf+Len){ fwrite(Obuf,1,Len,stdout); Ot=Obuf; } *Ot++=ch; } void flush(){ fwrite(Obuf,1,Ot-Obuf,stdout); Ot=Obuf; } void write(int x){ static int buf[100],d; if (x==0) pc('0'); else { if (x<0) pc('-'),x=-x; for (d=0;x;x/=10) buf[++d]=x%10+48; while (d) pc((char)buf[d--]); } } }
UPD(2019-04-21): 一个更短的IO模板(带自动flush)
namespace IO{ const int S=1<<20; char I[S+1],*Is=I,*It=I,O[S+1],*Ot=O; char gc(){return Is==It?((It=(Is=I)+fread(I,1,S,stdin))==I?EOF:*Is++):*Is++;} void flush(){fwrite(O,1,Ot-O,stdout),Ot=O;} void pc(char ch){Ot==O+S?flush(),*Ot++=ch:*Ot++=ch;} struct flusher{ ~flusher(){flush();}}Flusher; #define getchar gc #define putchar pc }
UPD(2020-04-06): 加了个输出的函数
namespace IO{ const int S=1<<20; char I[S+1],*Is=I,*It=I,O[S+1],*Ot=O; char gc(){return Is==It?((It=(Is=I)+fread(I,1,S,stdin))==I?EOF:*Is++):*Is++;} void flush(){fwrite(O,1,Ot-O,stdout),Ot=O;} void pc(char ch){Ot==O+S?flush(),*Ot++=ch:*Ot++=ch;} struct flusher{ ~flusher(){flush();}}Flusher; void write(LL x){if(x<0)pc('-'),write(-x);else{if(x>9)write(x/10);pc('0'+x%10);}} void writeln(LL x){write(x),pc(' ');} #define getchar gc #define putchar pc } using namespace IO;
手写 vector
namespace vecint{ typedef int T; const int maxlen=1e7; T _memp[maxlen],*memp=_memp; const int maxrec=1e4; T *p[30][maxrec]; int pcnt[30]; T *getmemp(int b){ int d=0; while ((1<<d)<b) d++; if (pcnt[d]) return p[d][--pcnt[d]]; T *res=memp; memp+=b; return res; } void recycmemp(T *a,int b){ if (!b) return; int d=0; while ((1<<d)<b) d++; if (pcnt[d]<maxrec) p[d][pcnt[d]++]=a; } struct vec{ int n,b; T *a; vec(){ n=0,b=0; a=memp; memp+=b; } void clear(){ n=0; } int size(){ return n; } int empty(){ return n==0; } T back(){ return a[n-1]; } void push_back(T v){ if (n==b){ b=max(b*2,1); T *nxt=getmemp(b); memcpy(nxt,a,n*sizeof(T)); recycmemp(a,n); a=nxt; } a[n++]=v; } T *begin(){ return a; } T *end(){ return a+n; } T &operator [](int i){ return a[i]; } }; }
Hash表
struct hash_map{ static const int Ti=233,mod=1<<16; int cnt,k[mod+1],v[mod+1],nxt[mod+1],fst[mod+1]; int Hash(int x){ int v=x&(mod-1); return v==0?mod:v; } void clear(){ cnt=0; memset(fst,0,sizeof fst); } void update(int x,int a){ int y=Hash(x); for (int p=fst[y];p;p=nxt[p]) if (k[p]==x){ v[p]=a; return; } k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt,v[cnt]=a; return; } int find(int x){ int y=Hash(x); for (int p=fst[y];p;p=nxt[p]) if (k[p]==x) return v[p]; return 0; } int &operator [] (int x){ int y=Hash(x); for (int p=fst[y];p;p=nxt[p]) if (k[p]==x) return v[p]; k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt; return v[cnt]=0; } }Map;
矩阵快速幂
namespace Matrix{ int t; struct Mat{ int v[N][N]; Mat(){} Mat(int x){ memset(v,0,sizeof v); for (int i=1;i<=t;i++) v[i][i]=x; } void Print(){ for (int i=1;i<=t;i++,puts("")) for (int j=1;j<=t;j++) printf("%3d ",v[i][j]); puts(""); } }M(0); Mat operator * (Mat A,Mat B){ Mat C(0); for (int i=1;i<=t;i++) for (int j=1;j<=t;j++) for (int k=1;k<=t;k++) C.v[i][j]=(1LL*A.v[i][k]*B.v[k][j]+C.v[i][j])%mod; return C; } Mat Pow(Mat x,LL y){ Mat ans(1); for (;y;y>>=1,x=x*x) if (y&1LL) ans=ans*x; return ans; } }
堆优化 dijkstra
int dis[N],vis[N]; struct Node{ int x,d; Node(){} Node(int _x,int _d){ x=_x,d=_d; } friend bool operator < (Node x,Node y){ return x.d>y.d; } }; priority_queue <Node> Q; void Dijkstra(){ while (!Q.empty()) Q.pop(); for (int i=1;i<=n;i++) dis[i]=2e9+5; dis[1]=0; memset(vis,0,sizeof vis); Q.push(Node(1,0)); while (!Q.empty()){ Node now=Q.top(); Q.pop(); int x=now.x; if (vis[x]) continue; vis[x]=1,dis[x]=now.d; for (int i=g.fst[x];i;i=g.nxt[i]) Q.push(Node(g.y[i],dis[x]+g.z[i])); } }
欧拉函数
int phi(int n){ int res=n; for (int 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; }
BSGS (需要加入 Hash 表模板)
int BSGS(int A,int B,int P){ int M=max((int)(0.8*sqrt(1.0*P)),1),AM=Pow(A,M,P); Map.clear(); for (int b=0,pw=B;b<M;b++,pw=1LL*pw*A%P) Map.update(pw,b+1); for (int a=M,pw=AM;a-M<P;a+=M,pw=1LL*pw*AM%P){ int v=Map.find(pw); if (v) return a-(v-1); } return -1; }
Berlekamp_Massey (BM)
#include <bits/stdc++.h> #define clr(x) memset(x,0,sizeof (x)) #define For(i,a,b) for (int i=a;i<=b;i++) #define Fod(i,b,a) for (int i=b;i>=a;i--) #define pb(x) push_back(x) #define mp(x,y) make_pair(x,y) #define fi first #define se second #define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I') #define outval(x) printf(#x" = %d ",x) #define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("") #define outtag(x) puts("----------"#x"----------") #define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R); For(_v2,L,R)printf("%d ",a[_v2]);puts(""); using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef vector <int> vi; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f|=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=0x1233,mod=1e9+7; void Add(int &x,int y){ if ((x+=y)>=mod) x-=mod; } void Del(int &x,int y){ if ((x-=y)<0) x+=mod; } int Pow(int x,int y){ int ans=1; for (;y;y>>=1,x=(LL)x*x%mod) if (y&1) ans=(LL)ans*x%mod; return ans; } int n,cnt; int a[N]; int Fail[N],delta[N]; vector <int> R[N]; int main(){ n=read(); For(i,1,n) a[i]=read(); R[0].clear(); cnt=0; For(i,1,n){ if (cnt==0){ if (a[i]){ Fail[cnt++]=i; delta[i]=a[i]; R[cnt].resize(0); R[cnt].resize(i,0); } continue; } int sum=0,m=R[cnt].size(); delta[i]=a[i]; Fail[cnt]=i; For(j,0,m-1) Add(sum,(LL)a[i-j-1]*R[cnt][j]%mod); Del(delta[i],sum); if (!delta[i]) continue; int id=cnt-1,v=i-Fail[id]+(int)R[id].size(); For(j,0,cnt-1) if (i-Fail[j]+(int)R[j].size()<v) id=j,v=i-Fail[j]+(int)R[j].size(); int tmp=(LL)delta[i]*Pow(delta[Fail[id]],mod-2)%mod; R[cnt+1]=R[cnt]; while (R[cnt+1].size()<v) R[cnt+1].pb(0); Add(R[cnt+1][i-Fail[id]-1],tmp); For(j,0,(int)R[id].size()-1) Del(R[cnt+1][i-Fail[id]+j],(LL)tmp*R[id][j]%mod); cnt++; } printf("%d ",(int)R[cnt].size()); For(i,0,(int)R[cnt].size()-1) printf("%d ",R[cnt][i]); puts(""); return 0; }
Cayley-Hamilton定理优化常系数线性递推(CH) (BZOJ4161)
#include <bits/stdc++.h> #define clr(x) memset(x,0,sizeof x) #define For(i,a,b) for (int i=a;i<=b;i++) #define Fod(i,b,a) for (int i=b;i>=a;i--) #define fi first #define se second #define pb(x) push_back(x) #define mp(x,y) make_pair(x,y) #define outval(x) printf(#x" = %d ",x) #define outtag(x) puts("---------------"#x"---------------") #define outarr(a,L,R) printf(#a"[%d..%d] = ",L,R); For(_x,L,R)printf("%d ",a[_x]);puts("") using namespace std; typedef long long LL; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f|=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=2005*2,mod=1e9+7; int n,k; int a[N],b[N]; void Add(int &x,int y){ if ((x+=y)>=mod) x-=mod; } void Del(int &x,int y){ if ((x-=y)<0) x+=mod; } int c[N]; void Mul(int *x,int *y){ static int z[N]; clr(z); For(i,0,k-1) For(j,0,k-1) Add(z[i+j],(LL)x[i]*y[j]%mod); Fod(i,2*k-2,k){ if (!z[i]) continue; For(j,1,k) Add(z[i-j],(LL)a[j]*z[i]%mod); } For(i,0,k-1) x[i]=z[i]; } void GetPoly(){ static int x[N]; int y=n; clr(x),clr(c),c[0]=x[1]=1; for (;y;y>>=1,Mul(x,x)) if (y&1) Mul(c,x); } int main(){ n=read(),k=read(); For(i,1,k) a[i]=(read()+mod)%mod; For(i,0,k-1) b[i]=(read()+mod)%mod; GetPoly(); int ans=0; For(i,0,k-1) Add(ans,(LL)b[i]*c[i]%mod); cout<<ans<<endl; return 0; }
带花树(一般图最大匹配)
#include <bits/stdc++.h> #define clr(x) memset(x,0,sizeof (x)) #define For(i,a,b) for (int i=(a);i<=(b);i++) #define pb(x) push_back(x) using namespace std; typedef long long LL; typedef vector <int> vi; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=505; int n,m; vi e[N]; queue <int> q; int match[N],vis[N],pre[N],tp[N]; int fa[N]; int getf(int x){ return fa[x]==x?x:fa[x]=getf(fa[x]); } int getlca(int x,int y){ static int Time=0; Time++; while (1){ if (x){ x=getf(x); if (vis[x]==Time) return x; vis[x]=Time; x=pre[match[x]]; } swap(x,y); } } void shrink(int x,int y,int lca){ while (getf(x)!=lca){ pre[x]=y,y=match[x]; if (tp[y]==2) tp[y]=1,q.push(y); if (fa[x]==x) fa[x]=lca; if (fa[y]==y) fa[y]=lca; x=pre[y]; } } int augment(int s){ if (match[s]) return 0; clr(tp),clr(pre); iota(fa+1,fa+n+1,1); while (!q.empty()) q.pop(); q.push(s); tp[s]=1; while (!q.empty()){ int x=q.front(); q.pop(); assert(tp[x]==1); for (auto y : e[x]){ if (getf(x)==getf(y)||tp[y]==2) continue; if (!tp[y]){ pre[y]=x; if (!match[y]){ do { int z=match[x]; match[x]=y,match[y]=x; y=z,x=pre[z]; } while (x); return 1; } tp[y]=2,tp[match[y]]=1; q.push(match[y]); } else { int lca=getlca(x,y); shrink(x,y,lca); shrink(y,x,lca); } } } return 0; } int main(){ n=read(),m=read(); For(i,1,m){ int x=read(),y=read(); e[x].pb(y),e[y].pb(x); } int res=0; For(i,1,n) res+=augment(i); cout<<res<<endl; For(i,1,n) cout<<match[i]<<" "; cout<<endl; return 0; }
Dinic (Updated on 2019-03-24)
#include <bits/stdc++.h> using namespace std; typedef long long LL; struct Edge{ int x,y,nxt,cap; Edge(){} Edge(int a,int b,int c,int d){ x=a,y=b,cap=c,nxt=d; } }; struct Network{ static const int N=105,M=5005*2,INF=0x7FFFFFFF; Edge e[M],tmp[M]; int n,S,T,fst[N],cur[N],cnt; int q[N],dis[N],head,tail; LL MaxFlow; void clear(int _n){ n=_n,cnt=1; memset(fst,0,sizeof fst); } void add(int a,int b,int c){ e[++cnt]=Edge(a,b,c,fst[a]),fst[a]=cnt; e[++cnt]=Edge(b,a,0,fst[b]),fst[b]=cnt; } void init(){ for (int i=1;i<=n;i++) cur[i]=fst[i]; } void init(int _S,int _T){ S=_S,T=_T,MaxFlow=0,init(); } int bfs(){ memset(dis,0,sizeof dis); head=tail=0,q[++tail]=T,dis[T]=1; while (head<tail) for (int x=q[++head],i=fst[x];i;i=e[i].nxt) if (!dis[e[i].y]&&e[i^1].cap){ dis[q[++tail]=e[i].y]=dis[x]+1; if (e[i].y==S) return 1; } return (bool)dis[S]; } int dfs(int x,int Flow){ if (x==T||!Flow) return Flow; int now=Flow; for (int &i=cur[x];i;i=e[i].nxt){ int y=e[i].y; if (dis[x]==dis[y]+1&&e[i].cap){ int d=dfs(y,min(now,e[i].cap)); e[i].cap-=d,e[i^1].cap+=d,now-=d; if (now==0) break; } } return Flow-now; } LL Dinic(){ while (bfs()) init(),MaxFlow+=dfs(S,INF); return MaxFlow; } LL Auto(int _S,int _T){ init(_S,_T); return Dinic(); } }g; int n,m,S,T; int main(){ scanf("%d%d%d%d",&n,&m,&S,&T); g.clear(n); while (m--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); g.add(a,b,c); } printf("%lld",g.Auto(S,T)); return 0; }
Dinic - 上下界网络流
#include <bits/stdc++.h> using namespace std; typedef long long LL; struct Edge{ int x,y,nxt; LL cap; Edge(){} Edge(int a,int b,LL c,int d){ x=a,y=b,cap=c,nxt=d; } }; struct Network{ static const int N=50010,M=175010*2; static const LL INF=1LL<<50; Edge e[M]; int n,S,T,fst[N],cur[N],cnt; int q[N],head,tail; LL MaxFlow,dis[N]; void clear(int _n){ n=_n,cnt=1; memset(fst,0,sizeof fst); } void add(int a,int b,LL c){ e[++cnt]=Edge(a,b,c,fst[a]),fst[a]=cnt; e[++cnt]=Edge(b,a,0,fst[b]),fst[b]=cnt; } void init(){ for (int i=1;i<=n;i++) cur[i]=fst[i]; } void init(int _S,int _T){ S=_S,T=_T,MaxFlow=0,init(); } int bfs(){ memset(dis,0,sizeof dis); head=tail=0; q[++tail]=T,dis[T]=1; while (head<tail) for (int x=q[++head],i=fst[x];i;i=e[i].nxt) if (!dis[e[i].y]&&e[i^1].cap){ if (e[i].y==T) return 1; dis[q[++tail]=e[i].y]=dis[x]+1; } return (bool)dis[S]; } LL dfs(int x,LL Flow){ if (x==T||!Flow) return Flow; LL now=Flow; for (int &i=cur[x];i;i=e[i].nxt){ int y=e[i].y; if (dis[x]==dis[y]+1&&e[i].cap){ LL d=dfs(y,min(now,e[i].cap)); e[i].cap-=d,e[i^1].cap+=d,now-=d; if (now==0) break; } } return Flow-now; } LL Dinic(){ while (bfs()) init(),MaxFlow+=dfs(S,INF); return MaxFlow; } LL Auto(int _S,int _T){ init(_S,_T); return Dinic(); } }; struct LU_Network{ static const int N=50010; static const LL INF=1LL<<50; Network g; int n,S,T; LL in[N],Sum; void clear(int _n){ memset(in,0,sizeof in); n=_n,S=n+1,T=n+2,Sum=0,g.clear(T); } void add(int x,int y,int L,int U){ g.add(x,y,U-L),in[x]-=L,in[y]+=L; } void build(){ for (int i=1;i<=n;i++) if (in[i]>0) g.add(S,i,in[i]),Sum+=in[i]; else if (in[i]<0) g.add(i,T,-in[i]); } bool CanFlow(){ build(); return g.Auto(S,T)>=Sum; } int cur,c1; bool CanFlow(int s,int t){ build(); c1=g.cnt; g.add(t,s,INF>>1); cur=g.cnt; return g.Auto(S,T)>=Sum; } LL MaxFlow(int s,int t){ if (!CanFlow(s,t)) return -1; return g.Auto(s,t); } LL MinFlow(int s,int t){ if (!CanFlow(s,t)) return -1; LL now=g.e[g.cnt].cap; g.e[g.cnt].cap=g.e[g.cnt^1].cap=0; return now-g.Auto(t,s); } }g; int read(){ int x=0; char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return x; } int n,m,S,T; signed main(){ n=read(),m=read(),S=read(),T=read(); g.clear(n); for (int i=1;i<=m;i++){ int x=read(),y=read(),L=read(),U=read(); g.add(x,y,L,U); } LL ans=g.MinFlow(S,T); if (!~ans) puts("please go home to sleep"); else printf("%lld",ans); return 0; }
动态DP(洛谷P4719)
#include <bits/stdc++.h> using namespace std; typedef long long LL; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f|=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=100005; const LL INF=1e17; int n,m; vector <int> e[N]; int fa[N],depth[N],son[N],size[N],top[N],dn[N],p[N],ap[N],Time=0; int v[N]; LL dp[N][2],g[N][2]; void dfs1(int x,int pre,int d){ depth[x]=d,fa[x]=pre,son[x]=0,size[x]=1; for (auto y : e[x]) if (y!=pre){ dfs1(y,x,d+1); size[x]+=size[y]; if (!son[x]||size[y]>size[son[x]]) son[x]=y; } } void dfs2(int x,int Top){ top[x]=Top; ap[p[x]=++Time]=x; if (son[x]) dfs2(son[x],Top),dn[x]=dn[son[x]]; else dn[x]=x; g[x][0]=0,g[x][1]=v[x]; for (auto y : e[x]) if (y!=fa[x]&&y!=son[x]){ dfs2(y,y); g[x][0]+=max(dp[y][0],dp[y][1]); g[x][1]+=dp[y][0]; } dp[x][0]=g[x][0],dp[x][1]=g[x][1]; if (son[x]){ dp[x][0]+=max(dp[son[x]][0],dp[son[x]][1]); dp[x][1]+=dp[son[x]][0]; } } struct Mat{ LL v00,v01,v10,v11; Mat(){} Mat(LL x){ v00=v01=v10=v11=-INF; if (x) v00=v11=0; } void init(LL x00,LL x01,LL x10,LL x11){ v00=x00,v01=x01,v10=x10,v11=x11; } void Print(){ cout << "Matrix: { " << v00 << " " << v01 << " " << v10 << " " << v11 << endl << "} "; } }_1(1); Mat operator * (Mat A,Mat B){ static Mat C; C.v00=max(A.v00+B.v00,A.v01+B.v10); C.v01=max(A.v00+B.v01,A.v01+B.v11); C.v10=max(A.v10+B.v00,A.v11+B.v10); C.v11=max(A.v10+B.v01,A.v11+B.v11); return C; } Mat val[N<<2]; void build(int rt,int L,int R){ if (L==R){ int x=ap[L]; val[rt].init(g[x][0],g[x][0],g[x][1],-INF); return; } int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; build(ls,L,mid); build(rs,mid+1,R); val[rt]=val[ls]*val[rs]; } void update(int rt,int L,int R,int x,LL v0,LL v1){ if (L==R){ val[rt].init(v0,v0,v1,-INF); return; } int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; if (x<=mid) update(ls,L,mid,x,v0,v1); else update(rs,mid+1,R,x,v0,v1); val[rt]=val[ls]*val[rs]; } Mat query(int rt,int L,int R,int xL,int xR){ if (xL<=L&&R<=xR) return val[rt]; int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; if (xR<=mid) return query(ls,L,mid,xL,xR); else if (xL>mid) return query(rs,mid+1,R,xL,xR); else return query(ls,L,mid,xL,xR)*query(rs,mid+1,R,xL,xR); } void update(int x,LL g0,LL g1){ static Mat M; int f=top[x]; while (x){ update(1,1,n,p[x],g[x][0]=g0,g[x][1]=g1); M=query(1,1,n,p[f],p[dn[x]]); x=fa[f]; if (x){ g0=g[x][0]-max(dp[f][0],dp[f][1])+max(M.v00,M.v10); g1=g[x][1]-dp[f][0]+M.v00; } dp[f][0]=M.v00; dp[f][1]=M.v10; f=top[x]; } } int main(){ n=read(),m=read(); for (int i=1;i<=n;i++) v[i]=read(); for (int i=1;i<n;i++){ int x=read(),y=read(); e[x].push_back(y); e[y].push_back(x); } dfs1(1,0,0); dfs2(1,1); build(1,1,n); while (m--){ int x=read(),y=read(); update(x,g[x][0],g[x][1]-v[x]+y); v[x]=y; printf("%lld ",max(dp[1][1],dp[1][0])); } return 0; }
动态DP - 全局平衡二叉树优化(洛谷P4751)
#pragma GCC optimize("Ofast","inline") #include <bits/stdc++.h> using namespace std; typedef int LL; namespace IO{ const int Len=1<<21; char Ibuf[Len+1],*Is=Ibuf,*It=Ibuf; char gc(){ if (Is==It){ It=(Is=Ibuf)+fread(Ibuf,1,Len,stdin); if (Is==It) return EOF; } return *Is++; } int read(){ int x=0,f=0; char ch=gc(); while (!isdigit(ch)) f|=ch=='-',ch=gc(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc(); return f?-x:x; } char Obuf[Len+1],*Ot=Obuf; void pc(char ch){ if (Ot==Obuf+Len){ fwrite(Obuf,1,Len,stdout); Ot=Obuf; } *Ot++=ch; } void flush(){ fwrite(Obuf,1,Ot-Obuf,stdout); Ot=Obuf; } void write(int x){ static int buf[100],d; if (x==0) pc('0'); else { if (x<0) pc('-'),x=-x; for (d=0;x;x/=10) buf[++d]=x%10+48; while (d) pc((char)buf[d--]); } } } using namespace IO; const int N=1000005; const LL INF=2147483647>>1; int n,m; vector <int> e[N]; int fa[N],depth[N],son[N],size[N],top[N],dn[N]; LL v[N],dp[N][2],g[N][2]; void dfs1(int x,int pre,int d){ depth[x]=d,fa[x]=pre,son[x]=0,size[x]=1; for (auto y : e[x]) if (y!=pre){ dfs1(y,x,d+1); size[x]+=size[y]; if (!son[x]||size[y]>size[son[x]]) son[x]=y; } } void dfs2(int x,int Top){ top[x]=Top; if (son[x]) dfs2(son[x],Top),dn[x]=dn[son[x]]; else dn[x]=x; g[x][0]=0,g[x][1]=v[x]; for (auto y : e[x]) if (y!=fa[x]&&y!=son[x]){ dfs2(y,y); g[x][0]+=max(dp[y][0],dp[y][1]); g[x][1]+=dp[y][0]; } dp[x][0]=g[x][0],dp[x][1]=g[x][1]; if (son[x]){ dp[x][0]+=max(dp[son[x]][0],dp[son[x]][1]); dp[x][1]+=dp[son[x]][0]; } } struct Mat{ LL v00,v01,v10,v11; Mat(){} Mat(LL x){ v00=v01=v10=v11=-INF; if (x) v00=v11=0; } Mat(LL x00,LL x01,LL x10,LL x11){ v00=x00,v01=x01,v10=x10,v11=x11; } void init(LL x00,LL x01,LL x10,LL x11){ v00=x00,v01=x01,v10=x10,v11=x11; } void Print(){ cout << "Matrix: { " << v00 << " " << v01 << " " << v10 << " " << v11 << " } "; } inline friend Mat operator * (Mat A,Mat &B){ return Mat( max(A.v00+B.v00,A.v01+B.v10), max(A.v00+B.v01,A.v01+B.v11), max(A.v10+B.v00,A.v11+B.v10), max(A.v10+B.v01,A.v11+B.v11)); } }_1(1); Mat val[N],G[N]; int Son[N][2]; void update(int x){ val[x]=val[Son[x][0]]*G[x]*val[Son[x][1]]; } int tmp[N],sz[N]; int build_bin(int pre,int L,int R){ if (L>R) return 0; int x=L,mid,l=L+1,r=R,ckv=(sz[L-1]+sz[R]+1)>>1; while (l<=r){ mid=(l+r)>>1; if (sz[mid]<=ckv) l=mid+1,x=mid; else r=mid-1; } mid=x,fa[x=tmp[x]]=pre; Son[x][0]=build_bin(x,L,mid-1); Son[x][1]=build_bin(x,mid+1,R); update(x); return x; } int build(int pre,int x){ for (int i=x;i;i=son[i]) for (auto y : e[i]) if (y!=son[i]&&y!=fa[i]) build(i,y); int n=tmp[0]=sz[0]=0; for (int i=x;i;i=son[i]){ tmp[++n]=i; sz[n]=sz[n-1]+size[i]-size[son[i]]; } return build_bin(pre,1,n); } int main(){ n=read(),m=read(); for (int i=1;i<=n;i++) v[i]=read(); for (int i=1;i<n;i++){ int x=read(),y=read(); e[x].push_back(y); e[y].push_back(x); } dfs1(1,0,0); dfs2(1,1); for (int i=1;i<=n;i++) G[i].init(g[i][0],g[i][0],g[i][1],-INF); val[0]=_1; int root=build(0,1),lastans=0; while (m--){ int x=read()^lastans,y=read(); g[x][1]+=y-v[x],v[x]=y; G[x].v10=g[x][1]; int f; while (x){ int f=fa[x]; if (f&&Son[f][0]!=x&&Son[f][1]!=x){ g[f][0]-=max(val[x].v00,val[x].v10); g[f][1]-=val[x].v00; } update(x); if (f&&Son[f][0]!=x&&Son[f][1]!=x){ g[f][0]+=max(val[x].v00,val[x].v10); g[f][1]+=val[x].v00; G[f].v00=g[f][0]; G[f].v01=g[f][0]; G[f].v10=g[f][1]; } x=f; } write(lastans=max(val[root].v00,val[root].v10)); pc(' '); } flush(); return 0; }
动态凸包(支持插入直线)(c++11)
const LL Q_Tag=-1.02e18; struct Line{ LL k,b; mutable function <const Line *()> nxt; bool operator < (const Line &x) const { if (x.b!=Q_Tag) return k!=x.k?k<x.k:b<x.b; const Line *s=nxt(); if (!s) return 0; return b-(*s).b<((*s).k-k)*x.k;//long double? } }; struct DynamicHull:public multiset <Line>{ int useless(iterator y){ iterator z=next(y); if (y==begin()){ if (z==end()) return 0; return (*y).k==(*z).k&&(*y).b<=(*z).b; } iterator x=prev(y); if (z==end()) return (*y).k==(*x).k&&(*y).b<=(*x).b; return ((*x).b-(*y).b)*((*z).k-(*y).k) >=((*y).b-(*z).b)*((*y).k-(*x).k);//long double? } void insert_line(LL k,LL b){ iterator x=insert({k,b}); x->nxt=[=]{return next(x)==end()?0:&*next(x);}; if (useless(x)){ erase(x); return; } while (next(x)!=end()&&useless(next(x))) erase(next(x)); while (x!=begin()&&useless(prev(x))) erase(prev(x)); } LL calc(LL x){ Line L=*lower_bound({x,Q_Tag}); return L.k*x+L.b; } };
多项式(求逆、开根、对数、指数、快速幂、除法、取模、多点求值、快速插值)
#include <bits/stdc++.h> using namespace std; typedef long long LL; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f|=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=1<<18,mod=998244353; void Add(int &x,int y){ if ((x+=y)>=mod) x-=mod; } void Del(int &x,int y){ if ((x-=y)<0) x+=mod; } int del(int x,int y){ return x-y<0?x-y+mod:x-y; } int Pow(int x,int y){ int ans=1; for (;y;y>>=1,x=(LL)x*x%mod) if (y&1) ans=(LL)ans*x%mod; return ans; } int randint(){ return ((rand()&65535)<<15)^(rand()&65535); } namespace Rem2{ int INIT_TAG=0; int t,w; #define fi first #define se second void init(){ INIT_TAG=1; srand('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I'); } pair <int,int> Mul_pii(pair <int,int> A,pair <int,int> B){ static int a,b; a=((LL)A.fi*B.fi+(LL)A.se*B.se%mod*w)%mod; b=((LL)A.fi*B.se+(LL)A.se*B.fi)%mod; return make_pair(a,b); } pair <int,int> Pow_pii(pair <int,int> x,int y){ pair <int,int> ans=make_pair(1,0); for (;y;y>>=1,x=Mul_pii(x,x)) if (y&1) ans=Mul_pii(ans,x); return ans; } int Sqrt(int x){ if (!INIT_TAG) init(); if (x==0) return 0; if (Pow(x,(mod-1)/2)!=1) return -1; do { t=randint()%(mod-1)+1; w=((LL)t*t+mod-x)%mod; } while (Pow(w,(mod-1)/2)==1); pair <int,int> res=Pow_pii(make_pair(t,1),(mod+1)/2); return min(res.fi,mod-res.fi); } } namespace Polynomial{ namespace Fast{ const int N=1<<18; int n,Log[N+1],Fac[N+1],InvFac[N+1],Inv[N+1]; int ww[N*2],*Ew=ww,*w[N+1]; int iww[N*2],*Ei=iww,*iw[N+1]; int INIT_TAG=0; void init(int _n){ INIT_TAG=1; Log[1]=0,n=_n; for (int i=2;i<=N;i++) Log[i]=Log[i>>1]+1; for (int i=Fac[0]=1;i<=N;i++) Fac[i]=(LL)Fac[i-1]*i%mod; InvFac[N]=Pow(Fac[N],mod-2); for (int i=N;i>=1;i--) InvFac[i-1]=(LL)InvFac[i]*i%mod; for (int i=1;i<=N;i++) Inv[i]=(LL)InvFac[i]*Fac[i-1]%mod; for (int d=0;d<=Log[n];d++){ w[d]=Ew,iw[d]=Ei; int n=1<<d; w[d][0]=1,w[d][1]=Pow(3,(mod-1)/n); for (int i=2;i<n;i++) w[d][i]=(LL)w[d][i-1]*w[d][1]%mod; iw[d][0]=1,iw[d][1]=Pow(w[d][1],mod-2); for (int i=2;i<n;i++) iw[d][i]=(LL)iw[d][i-1]*iw[d][1]%mod; Ew+=n,Ei+=n; } } int Rev[N+1],A[N+1],B[N+1]; void FFT(int a[],int n,int **w){ if (!INIT_TAG) init(N); for (int i=0;i<n;i++) if (Rev[i]<i) swap(a[i],a[Rev[i]]); for (int t=1,d=1;d<n;t++,d<<=1) for (int i=0;i<n;i+=(d<<1)) for (int j=0,*W=w[t];j<d;j++){ int tmp=(LL)(*W++)*a[i+j+d]%mod; a[i+j+d]=del(a[i+j],tmp); Add(a[i+j],tmp); } } vector <int> Mul(vector <int> &a,vector <int> &b){ static vector <int> res; res.clear(); LL Br=(LL)a.size()*b.size(); LL FF=(a.size()+b.size())*Log[a.size()+b.size()]*10+100; if (Br<=FF){ for (int i=0;i<a.size()+b.size();i++) res.push_back(0); for (int i=0;i<a.size();i++) for (int j=0;j<b.size();j++) res[i+j]=((LL)a[i]*b[j]+res[i+j])%mod; } else { int n=1,d=0; for (;n<a.size()+b.size();n<<=1,d++); for (int i=0;i<n;i++) Rev[i]=(Rev[i>>1]>>1)|((i&1)<<(d-1)),A[i]=B[i]=0; for (int i=0;i<a.size();i++) A[i]=a[i]; for (int i=0;i<b.size();i++) B[i]=b[i]; // w[0]=1,w[1]=Pow(3,(mod-1)/n); // for (int i=2;i<n;i++) // w[i]=(LL)w[i-1]*w[1]%mod; FFT(A,n,w),FFT(B,n,w); for (int i=0;i<n;i++) A[i]=(LL)A[i]*B[i]%mod; // w[1]=Pow(w[1],mod-2); // for (int i=2;i<n;i++) // w[i]=(LL)w[i-1]*w[1]%mod; FFT(A,n,iw); int inv=Pow(n,mod-2); for (int i=0;i<n;i++) res.push_back((int)((LL)inv*A[i]%mod)); } while (!res.empty()&&!res.back()) res.pop_back(); return res; } vector <int> MulInv(vector <int> &a,vector <int> &b){ static vector <int> res; res.clear(); int n=1,d=0; for (;n<a.size()*2+b.size();n<<=1,d++); for (int i=0;i<n;i++) Rev[i]=(Rev[i>>1]>>1)|((i&1)<<(d-1)),A[i]=B[i]=0; for (int i=0;i<a.size();i++) A[i]=a[i]; for (int i=0;i<b.size();i++) B[i]=b[i]; // w[0]=1,w[1]=Pow(3,(mod-1)/n); // for (int i=2;i<n;i++) // w[i]=(LL)w[i-1]*w[1]%mod; FFT(A,n,w),FFT(B,n,w); for (int i=0;i<n;i++) A[i]=(LL)A[i]*A[i]%mod*B[i]%mod; // w[1]=Pow(w[1],mod-2); // for (int i=2;i<n;i++) // w[i]=(LL)w[i-1]*w[1]%mod; FFT(A,n,iw); int inv=Pow(n,mod-2); for (int i=0;i<n;i++) res.push_back((int)((LL)inv*A[i]%mod)); while (!res.empty()&&!res.back()) res.pop_back(); return res; } } struct Poly{ vector <int> v; Poly(){ v.clear(); } Poly(int x){ v.clear(); v.push_back(x); } Poly(vector <int> x){ v=x; } int operator ()(int x){ int ans=0,y=1; for (int i=0;i<v.size();i++) ans=((LL)v[i]*y+ans)%mod,y=(LL)y*x%mod; return ans; } int size(){ return v.size(); } void print(){ for (int i=0;i<v.size();i++) printf("%d ",v[i]); } void print(int x){ for (int i=0;i<x;i++) printf("%d ",i>=v.size()?0:v[i]); } void print(string s){ print(),cout << s; } void clear(){ v.clear(); } void push_back(int x){ v.push_back(x); } void pop_back(){ v.pop_back(); } int empty(){ return v.empty(); } int back(){ return v.back(); } int &operator [](int x){ return v[x]; } void operator += (Poly A){ while (v.size()<A.size()) v.push_back(0); for (int i=0;i<A.size();i++) Add(v[i],A[i]); } void operator -= (Poly &A){ while (v.size()<A.size()) v.push_back(0); for (int i=0;i<A.size();i++) Del(v[i],A[i]); } void operator *= (Poly &A); void Derivation(){ for (int i=0;i<v.size()-1;i++) v[i]=(LL)v[i+1]*(i+1)%mod; v.pop_back(); } void Integral(){ v.push_back(0); for (int i=v.size()-2;i>=0;i--) v[i+1]=(LL)v[i]*Fast :: Inv[i+1]%mod; v[0]=0; } void operator *= (int x){ for (int i=0;i<v.size();i++) v[i]=(LL)v[i]*x%mod; } }pp; //struct Poly end------------- Poly operator + (Poly A,Poly B){ pp.clear(); for (int i=0;i<max(A.size(),B.size());i++) pp.push_back(0); for (int i=0;i<A.size();i++) Add(pp[i],A[i]); for (int i=0;i<B.size();i++) Add(pp[i],B[i]); return pp; } Poly operator - (Poly A,Poly B){ pp.clear(); for (int i=0;i<max(A.size(),B.size());i++) pp.push_back(0); for (int i=0;i<A.size();i++) Add(pp[i],A[i]); for (int i=0;i<B.size();i++) Del(pp[i],B[i]); return pp; } Poly operator * (Poly A,Poly B){ return Poly(Fast :: Mul(A.v,B.v)); } void Poly :: operator *= (Poly &A){ v=Fast :: Mul(v,A.v); } Poly operator * (Poly A,int x){ pp=A; for (int i=0;i<A.size();i++) pp[i]=(LL)pp[i]*x%mod; return pp; } Poly Inverse(Poly a,int n); Poly operator / (Poly A,Poly B){//Divide int n=A.size(),m=B.size(); reverse(A.v.begin(),A.v.end()); reverse(B.v.begin(),B.v.end()); int k=n-m+1; if (k<0) return Poly(0); while (A.size()>k) A.pop_back(); while (B.size()>k) B.pop_back(); A=A*Inverse(B,k); while (A.size()>k) A.pop_back(); reverse(A.v.begin(),A.v.end()); return A; } Poly operator % (Poly A,Poly B){//Modulo while (!A.empty()&&!A.back()) A.pop_back(); while (!B.empty()&&!B.back()) B.pop_back(); A=A-A/B*B; while (A.size()>=B.size()) A.pop_back(); while (!A.empty()&&!A.back()) A.pop_back(); return A; } Poly Derivation(Poly A){ for (int i=0;i<A.size()-1;i++) A[i]=(LL)A[i+1]*(i+1)%mod; A.pop_back(); return A; } Poly Integral(Poly A){ A.push_back(0); for (int i=A.size()-2;i>=0;i--) A[i+1]=(LL)A[i]*Fast :: Inv[i+1]%mod; A[0]=0; return A; } Poly Inverse(Poly a,int n){ static Poly A,B; while (!a.empty()&&!a.back()) a.pop_back(); if (a.empty()) return a; A.clear(),B.clear(); B.push_back(a[0]); A.push_back(Pow(B[0],mod-2)); for (int t=1;t<n;){ for (int i=t;i<min(a.size(),(t<<1));i++) B.push_back(a[i]); t<<=1; A=A*2-Poly(Fast :: MulInv(A.v,B.v)); while (A.size()>t) A.pop_back(); } while (A.size()>n) A.pop_back(); return A; } Poly Sqrt(Poly a,int n){ static Poly A,B; while (!a.empty()&&!a.back()) a.pop_back(); if (a.empty()) return a; A.clear(),B.clear(); B.push_back(a[0]); A.push_back(Rem2 :: Sqrt(B[0])); for (int t=1;t<n;){ for (int i=t;i<min(a.size(),(t<<1));i++) B.push_back(a[i]); t<<=1; A+=B*Inverse(A,t); while (A.size()>t) A.pop_back(); A*=499122177; } if (A[0]>mod-A[0]) for (int i=0;i<A.size();i++) A[i]=(mod-A[i])%mod; while (A.size()>n) A.pop_back(); return A; } Poly Ln(Poly a,int n){ while (!a.empty()&&!a.back()) a.pop_back(); if (a.empty()||a[0]!=1) return a; a=Integral(Derivation(a)*Inverse(a,n)); while (a.size()>n) a.pop_back(); return a; } Poly Exp(Poly a,int n){ static Poly A,B; while (!a.empty()&&!a.back()) a.pop_back(); if (a.empty()) return Poly(1); if (a[0]!=0) return a; A.clear(),B.clear(); B.push_back(1); A.push_back(a[0]); for (int t=1;t<n;){ for (int i=t;i<min(a.size(),(t<<1));i++) A.push_back(a[i]); t<<=1; B=B*(Poly(1)+A-Ln(B,t)); while (B.size()>t) B.pop_back(); } while (B.size()>n) B.pop_back(); return B; } Poly PolyPow(Poly x,int y,int n){ static Poly A,B; int k0=0,kc,ivkc; while (!x.empty()&&!x.back()) x.pop_back(); if (x.empty()) return x; while (k0<x.size()&&x[k0]==0) k0++; kc=x[k0],ivkc=Pow(kc,mod-2); A.clear(); for (int i=k0;i<x.size();i++) A.push_back((int)((LL)x[i]*ivkc%mod)); A=Exp(Ln(A,n)*y,n); B.clear(); if ((LL)k0*y>=n) return B; kc=Pow(kc,y),k0*=y; for (int i=0;i<k0;i++) B.push_back(0); for (int i=0;i<min(A.size(),n-k0);i++) B.push_back((int)((LL)A[i]*kc%mod)); while (B.size()>n) B.pop_back(); return B; } namespace Qiuzhi{ Poly P[N<<2],f[N<<2],M; vector <int> x,y; int n; void GetP(int rt,int L,int R){ if (L==R){ P[rt].clear(); P[rt].push_back((mod-x[L])%mod); P[rt].push_back(1); return; } int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; GetP(ls,L,mid); GetP(rs,mid+1,R); P[rt]=P[ls]*P[rs]; } void qiuzhi(int rt,int L,int R){ if (f[rt].empty()) f[rt].push_back(0); if (L==R) return (void)(y[L]=f[rt][0]); int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; f[ls]=f[rt]%P[ls]; f[rs]=f[rt]%P[rs]; qiuzhi(ls,L,mid); qiuzhi(rs,mid+1,R); } vector <int> Get_Val(vector <int> A,Poly F){ n=A.size(); x.clear(),y.clear(); for (int i=0;i<n;i++){ x.push_back(A[i]); y.push_back(0); } GetP(1,0,n-1); f[1]=F; qiuzhi(1,0,n-1); return y; } } namespace Chazhi{ Poly P[N<<2],M; vector <int> x,y; int n; void GetP(int rt,int L,int R){ if (L==R){ P[rt].clear(); P[rt].push_back((mod-x[L])%mod); P[rt].push_back(1); return; } int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; GetP(ls,L,mid); GetP(rs,mid+1,R); P[rt]=P[ls]*P[rs]; } Poly chazhi(int rt,int L,int R){ if (L==R) return Poly(y[L]); int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; return chazhi(ls,L,mid)*P[rs]+chazhi(rs,mid+1,R)*P[ls]; } Poly Get_Poly(vector <int> A,vector <int> B){ n=A.size(); x=A; int Product=1; GetP(1,0,n-1); M=Derivation(P[1]); y=Qiuzhi :: Get_Val(A,M); for (int i=0;i<y.size();i++) y[i]=(LL)B[i]*Pow(y[i],mod-2)%mod; return chazhi(1,0,n-1); } } }// be careful about init!!!!!! using namespace Polynomial; Poly A,B; vector <int> x,y; int main(){ Fast :: init(1<<18); int n=read(); x.clear(),y.clear(); for (int i=0;i<n;i++){ x.push_back(read()); y.push_back(read()); } A=Chazhi :: Get_Poly(x,y); int m=read(); x.clear(); for (int i=0;i<m;i++) x.push_back(read()); y=Qiuzhi :: Get_Val(x,A); for (int i=0;i<m;i++) printf("%d ",y[i]); return 0; }
UPD2020-07-22(vector 版):
#include <bits/stdc++.h> #define clr(x) memset(x,0,sizeof (x)) #define For(i,a,b) for (int i=(a);i<=(b);i++) #define Fod(i,b,a) for (int i=(b);i>=(a);i--) #define fi first #define se second #define kill _z_kill #define pb(x) push_back(x) #define mp(x,y) make_pair(x,y) #define outval(x) cerr<<#x" = "<<x<<endl #define outv(x) cerr<<#x" = "<<x<<" " #define outtag(x) cerr<<"--------------"#x"---------------"<<endl #define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = "; For(_x,L,R) cerr<<a[_x]<<" ";cerr<<endl; #define User_Time ((double)clock()/CLOCKS_PER_SEC) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef unsigned uint; typedef long double LD; typedef vector <int> vi; typedef pair <int,int> pii; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } template <class T> void ckmax(T &x,T y){ if (x<y) x=y; } template <class T> void ckmin(T &x,T y){ if (y<x) x=y; } const int mod=998244353; int Pow(int x,int y){ int ans=1; for (;y;y>>=1,x=(LL)x*x%mod) if (y&1) ans=(LL)ans*x%mod; return ans; } void Add(int &x,int y){ if ((x+=y)>=mod) x-=mod; } void Del(int &x,int y){ if ((x-=y)<0) x+=mod; } int Add(int x){ return x>=mod?x-mod:x; } int Del(int x){ return x<0?x+mod:x; } const int N=(1<<18)+1; int Fac[N],Inv[N],Iv[N]; namespace fft{ int R[N]; vi w[23]; void prework(){ int d=log(N)/log(2)+0.5; For(i,1,d){ w[i].resize(1<<i); w[i][0]=1,w[i][1]=Pow(3,(mod-1)>>i); For(j,2,(1<<i)-1) w[i][j]=(LL)w[i][j-1]*w[i][1]%mod; } } void init(int n){ int d=0; while ((1<<d)<n) d++; For(i,0,n-1) R[i]=(R[i>>1]>>1)|((i&1)<<(d-1)); } void FFT(int *a,int n,int flag){ For(i,0,n-1) if (i<R[i]) swap(a[i],a[R[i]]); for (int t=1,d=1;d<n;d<<=1,t++) for (int i=0;i<n;i+=d<<1){ int *W=&w[t][0]; For(j,0,d-1){ int tmp=(LL)a[i+j+d]*(*W++)%mod; a[i+j+d]=Del(a[i+j]-tmp); a[i+j]=Add(a[i+j]+tmp); } } if (flag<0){ reverse(a+1,a+n); int inv=Pow(n,mod-2); For(i,0,n-1) a[i]=(LL)a[i]*inv%mod; } } } void prework(){ int n=N-1; Fac[0]=1; For(i,1,n) Fac[i]=(LL)Fac[i-1]*i%mod; Inv[n]=Pow(Fac[n],mod-2); Fod(i,n,1) Inv[i-1]=(LL)Inv[i]*i%mod; For(i,1,n) Iv[i]=(LL)Inv[i]*Fac[i-1]%mod; fft::prework(); } using fft::FFT; vi fix(vi a,int n){ a.resize(n); return a; } int calcfx(vi f,int x){ int v=1,ans=0; For(i,0,(int)f.size()-1){ Add(ans,(LL)v*f[i]%mod); v=(LL)v*x%mod; } return ans; } vi operator + (vi a,vi b){ a.resize(max(a.size(),b.size())); For(i,0,(int)b.size()-1) Add(a[i],b[i]); return a; } vi operator - (vi a,vi b){ a.resize(max(a.size(),b.size())); For(i,0,(int)b.size()-1) Del(a[i],b[i]); return a; } vi operator * (vi a,int b){ for (auto &i : a) i=(LL)i*b%mod; return a; } vi operator * (vi a,vi b){ if (a.empty()||b.empty()) return vi(); int nn=a.size()+b.size()-1,n=1<<(int)(log(nn)/log(2)+1); a.resize(n),b.resize(n); fft::init(n); FFT(&a[0],n,1),FFT(&b[0],n,1); For(i,0,n-1) a[i]=(LL)a[i]*b[i]%mod; FFT(&a[0],n,-1); return fix(a,nn); } const int inv2=(mod+1)/2; vi polyinv(vi a){ if (a.size()==1) return vi(1,Pow(a[0],mod-2)); int n=a.size(); vi b=polyinv(fix(a,(n+1)/2)); int len=1<<(int)(log(n+(int)b.size())/log(2)+1); vi c=fix(b,len),d=fix(a,len); fft::init(len),FFT(&c[0],len,1),FFT(&d[0],len,1); For(i,0,len-1) c[i]=(LL)c[i]*c[i]%mod*d[i]%mod; FFT(&c[0],len,-1); b.resize(n); For(i,(n+1)/2,n-1) Del(b[i],c[i]); return b; } vi Der(vi a){ For(i,1,(int)a.size()-1) a[i-1]=(LL)a[i]*i%mod; a.pop_back(); return a; } vi Int(vi a){ a.pb(0); Fod(i,(int)a.size()-1,1) a[i]=(LL)a[i-1]*Iv[i]%mod; a[0]=0; return a; } vi polyln(vi a){ return Int(fix(Der(a)*polyinv(a),(int)a.size()-1)); } vi polyexp(vi a){ if (a.size()==1) return vi(1,1); int n=a.size(); vi b=polyexp(fix(a,(n+1)/2)); return fix(b+b*(a-polyln(fix(b,n))),n); } vi operator / (vi a,vi b){ int n=a.size(),m=b.size(); if (n<m) return vi(); reverse(a.begin(),a.end()); reverse(b.begin(),b.end()); a=fix(fix(a,n-m+1)*polyinv(fix(b,n-m+1)),n-m+1); reverse(a.begin(),a.end()); return a; } vi operator % (vi a,vi b){ return fix(a-a/b*b,(int)b.size()-1); } vi polypow(vi a,int k){ // return polyexp(polyln(a)*k); int p=0; while (p<(int)a.size()&&!a[p]) p++; if ((LL)p*k>=(int)a.size()) return vi(); vi b(a.begin()+p,a.end()); int coef=b[0],inv=Pow(coef,mod-2),powcoef=Pow(coef,k); b=polyexp(polyln(b*inv)*k)*powcoef; vi c(p*k+(int)b.size()); For(i,0,(int)b.size()-1) c[i+p*k]=b[i]; return fix(c,a.size()); } int Sqrt(int x){ const int g=3; unordered_map <int,int> Map; int sq=(int)sqrt(mod-1)+1,pv=Pow(g,sq); for (int i=0,v=1;i<=sq;i++,v=(LL)v*pv%mod) Map[v]=i; for (int i=0,v=x;i<sq;i++,v=(LL)v*g%mod) if (Map.count(v)){ int ind=((LL)Map[v]*sq-i+mod-1)%(mod-1); if (ind&1) return -1; ind/=2; int res=Pow(g,ind); return min(res,(mod-res)%mod); } return -1; } vi polysqrt(vi a){ if (a.size()==1) return vi(1,Sqrt(a[0])); int n=a.size(); vi b=fix(polysqrt(fix(a,(n+1)/2)),n); return fix((b+a*polyinv(b))*((mod+1)/2),n); } namespace eval_inter{ int n; vi f,x,y,prod[N*4]; void getprod(int rt,int L,int R){ if (L==R){ prod[rt]={Del(-x[L]),1}; return; } int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; getprod(ls,L,mid); getprod(rs,mid+1,R); prod[rt]=prod[ls]*prod[rs]; } void gety(int rt,int L,int R,vi f){ f=fix(f%prod[rt],(int)prod[rt].size()-1); if (L==R) return (void)(y[L]=f[0]); int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; gety(ls,L,mid,f); gety(rs,mid+1,R,f); } vi eval(vi _f,vi _x){ n=_x.size(); if (!n) return vi(); f=_f,x=_x,y.resize(n); getprod(1,0,n-1); gety(1,0,n-1,f); return y; } vi getf(int rt,int L,int R){ if (L==R) return vi(1,y[L]); int mid=(L+R)>>1,ls=rt<<1,rs=ls|1; return getf(ls,L,mid)*prod[rs]+getf(rs,mid+1,R)*prod[ls]; } vi inter(vi _x,vi _y){ n=_x.size(); if (!n) return vi(); x=_x,y.resize(n); getprod(1,0,n-1); vi M=Der(prod[1]); gety(1,0,n-1,M); For(i,0,n-1) y[i]=(LL)_y[i]*Pow(y[i],mod-2)%mod; return getf(1,0,n-1); } } int main(){ prework(); //LOJ #150 int n=read(),k=read(); vi f(n+1); For(i,0,n) f[i]=read(); vi g=fix(Der(polypow(vi(1,1)+polyln(vi(1,Del(2-f[0]))+f-polyexp(Int(polyinv(polysqrt(f))))),k)),n); For(i,0,n-1) printf("%d ",g[i]); puts(""); /* //NFLSOJ #53 int n=read(); vi x(n),y(n); For(i,0,n-1) x[i]=read(),y[i]=read(); vi f=eval_inter::inter(x,y); // For(i,0,n-1) // printf("%d ",f[i]); // puts(""); int m=read(); vi z(m); For(i,0,m-1) z[i]=read(); z=eval_inter::eval(f,z); For(i,0,m-1) printf("%d ",z[i]); puts(""); */ return 0; }
exBSGS (需要加入 Hash 表模板)
int ExBSGS(int A,int B,int P){ A%=P,B%=P; int k=0,v=1; while (1){ int g=gcd(A,P); if (g==1) break; if (B%g) return -1; k++,B/=g,P/=g,v=1LL*v*(A/g)%P; if (v==B) return k; } if (P==1) return k; int M=max((int)sqrt(1.0*P),1),AM=Pow(A,M,P); Map.clear(); for (int b=0,pw=B;b<M;b+=1,pw=1LL*pw*A%P) Map.update(pw,b+1); for (int a=M,pw=1LL*v*AM%P;a-M<P;a+=M,pw=1LL*pw*AM%P){ int v=Map.find(pw); if (v) return a-(v-1)+k; } return -1; }
exgcd
int exgcd(int a,int b,int &x,int &y){ if (!b){ x=1,y=0; return a; } int res=exgcd(b,a%b,y,x); y-=(a/b)*x; return res; }
exCRT
LL ex_gcd(LL a,LL b,LL &x,LL &y){ if (!b){ x=1,y=0; return a; } LL res=ex_gcd(b,a%b,y,x); y-=x*(a/b); return res; } LL gcd(LL a,LL b){ return b?gcd(b,a%b):a; } LL inv(LL v,LL p){ LL x,y,g=ex_gcd(v,p,x,y); if (g>1) return -1; return (x+p)%p; } LL Mul(LL a,LL b,LL p){ a=(a%p+p)%p; b=(b%p+p)%p; LL ans=0; for (;a;a>>=1,b=(b<<1)%p) if (a&1LL) ans=(ans+b)%p; return ans; } bool CRT(LL w1,LL p1,LL w2,LL p2,LL &w,LL &p){ LL x,y,z=w2-w1,g=ex_gcd(p1,p2,x,y); if (z%g) return 0; LL t=z/g; x=Mul(x,t,p2/g); p=p1/g*p2; w=((w1+Mul(x,p1,p))%p+p)%p; return 1; }
exkmp
#include <bits/stdc++.h> using namespace std; void exKMP(char s[],char t[],int g[],int f[],int n,int m){ int Max=0; f[0]=m; for (int i=1;i<m;i++){ f[i]=max(0,min(f[i-Max],Max+f[Max]-i)); while (i+f[i]<m&&t[f[i]]==t[i+f[i]]) f[i]++; if (!Max||i+f[i]>Max+f[Max]) Max=i; } Max=0; for (int i=0;i<n;i++){ g[i]=max(0,min(f[i-Max],Max+g[Max]-i)); while (i+g[i]<n&&t[g[i]]==s[i+g[i]]) g[i]++; if (!Max||i+g[i]>Max+g[Max]) Max=i; } } int main(){ return 0; }
exLucas
LL Pow(LL x,LL y,LL mod){ if (y==0) return 1LL; LL xx=Pow(x,y/2,mod); xx=xx*xx%mod; if (y&1LL) xx=xx*x%mod; return xx; } void ex_gcd(LL a,LL b,LL &x,LL &y){ if (!b) x=1,y=0; else ex_gcd(b,a%b,y,x),y-=a/b*x; } LL Inv(LL X,LL mod){ if (!X) return 0; LL a=X,b=mod,x,y; ex_gcd(a,b,x,y); x=(x%b+b)%b; return x; } LL ex_lucas(LL n,LL pi,LL pk){ if (!n) return 1LL; LL ans=1; for (LL i=2;i<=pk;i++) if (i%pi) ans=ans*i%pk; ans=Pow(ans,n/pk,pk); for (LL i=2;i<=n%pk;i++) if (i%pi) ans=ans*i%pk; return ans*ex_lucas(n/pi,pi,pk)%pk; } LL C(LL n,LL m,LL pi,LL pk){ if (m>n) return 0; LL a=ex_lucas(n,pi,pk),b=ex_lucas(m,pi,pk),c=ex_lucas(n-m,pi,pk); LL k=0,ans; for (LL i=n;i;i/=pi,k+=i); for (LL i=m;i;i/=pi,k-=i); for (LL i=n-m;i;i/=pi,k-=i); ans=a*Inv(b,pk)%pk*Inv(c,pk)%pk*Pow(pi,k,pk)%pk; return ans*(P/pk)%P*Inv(P/pk,pk)%P; } LL C(LL n,LL m){ LL ans=0; for (int i=1;i<=cnt;i++) ans=(ans+C(n,m,px[i],Pow(px[i],py[i],P+1)))%P; return ans; }
二次剩余
int Pow(int x,int y){ int ans=1; for (;y;y>>=1,x=(LL)x*x%mod) if (y&1) ans=(LL)ans*x%mod; return ans; } int randint(){ return ((rand()&65535)<<15)^(rand()&65535); } namespace Rem2{ int INIT_TAG=0; int t,w; #define fi first #define se second void init(){ INIT_TAG=1; srand('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I'); } pair <int,int> Mul_pii(pair <int,int> A,pair <int,int> B){ static int a,b; a=((LL)A.fi*B.fi+(LL)A.se*B.se%mod*w)%mod; b=((LL)A.fi*B.se+(LL)A.se*B.fi)%mod; return make_pair(a,b); } pair <int,int> Pow_pii(pair <int,int> x,int y){ pair <int,int> ans=make_pair(1,0); for (;y;y>>=1,x=Mul_pii(x,x)) if (y&1) ans=Mul_pii(ans,x); return ans; } int Sqrt(int x){ if (!INIT_TAG) init(); if (x==0) return 0; if (Pow(x,(mod-1)/2)!=1) return -1; do { t=randint()%(mod-1)+1; w=((LL)t*t+mod-x)%mod; } while (Pow(w,(mod-1)/2)==1); pair <int,int> res=Pow_pii(make_pair(t,1),(mod+1)/2); return min(res.fi,mod-res.fi); } }
FFT
const int N=1<<18; struct C{ double r,i; C(){} C(double _r,double _i){r=_r,i=_i;} friend C operator + (C a,C b){return C(a.r+b.r,a.i+b.i);} void operator += (C a){r+=a.r,i+=a.i;} friend C operator - (C a,C b){return C(a.r-b.r,a.i-b.i);} friend C operator * (C a,double b){return C(a.r*b,a.i*b);} friend C operator * (C a,C b){return C(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);} C conj(){return C(r,-i);} }a[N],b[N]; vector <C> w[19]; const double pi=acos(-1.0); void prework(){ int d=18; For(i,0,d){ int n=1<<i; w[i].resize(n); For(j,0,n-1) w[i][j]=C(cos(pi*2*j/n),sin(pi*2*j/n)); } } int R[N]; void init(int n){ int d=0; while ((1<<d)<n) d++; For(i,0,n-1) R[i]=(R[i>>1]>>1)|((i&1)<<(d-1)); } void dft(C *a,int n,int flag){ init(n); For(i,0,n-1) if (R[i]<i) swap(a[i],a[R[i]]); for (int t=1,d=1;d<n;d<<=1,t++) for (int i=0;i<n;i+=d<<1){ C *W=w[t].data(); for (int j=0;j<d;j++){ C tmp=a[i+j+d]*(*W++); a[i+j+d]=a[i+j]-tmp; a[i+j]+=tmp; } } if (flag<0){ reverse(a+1,a+n); For(i,0,n-1) a[i].r/=n,a[i].i/=n; } }
FFT - 共轭常数优化(MTT?)(UOJ#34)
#include <bits/stdc++.h> #define clr(x) memset(x,0,sizeof (x)) #define For(i,a,b) for (int i=(a);i<=(b);i++) using namespace std; typedef long long LL; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=1<<18; struct C{ double r,i; C(){} C(double _r,double _i){r=_r,i=_i;} friend C operator + (C a,C b){return C(a.r+b.r,a.i+b.i);} void operator += (C a){r+=a.r,i+=a.i;} friend C operator - (C a,C b){return C(a.r-b.r,a.i-b.i);} friend C operator * (C a,double b){return C(a.r*b,a.i*b);} friend C operator * (C a,C b){return C(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);} C conj(){return C(r,-i);} }a[N],b[N]; vector <C> w[19]; const double pi=acos(-1.0); void prework(){ int d=18; For(i,0,d){ int n=1<<i; w[i].resize(n); For(j,0,n-1) w[i][j]=C(cos(pi*2*j/n),sin(pi*2*j/n)); } } int R[N]; void init(int n){ int d=0; while ((1<<d)<n) d++; For(i,0,n-1) R[i]=(R[i>>1]>>1)|((i&1)<<(d-1)); } void dft(C *a,int n,int flag){ init(n); For(i,0,n-1) if (R[i]<i) swap(a[i],a[R[i]]); for (int t=1,d=1;d<n;d<<=1,t++) for (int i=0;i<n;i+=d<<1){ C *W=w[t].data(); for (int j=0;j<d;j++){ C tmp=a[i+j+d]*(*W++); a[i+j+d]=a[i+j]-tmp; a[i+j]+=tmp; } } if (flag<0){ reverse(a+1,a+n); For(i,0,n-1) a[i].r/=n,a[i].i/=n; } } void mtt(C *a,C *b,int n){ static C t[N]; For(i,0,n-1) t[i].r=a[i].r,t[i].i=b[i].r; dft(t,n,1); For(i,0,n-1){ C p=t[i],q=t[(n-i)&(n-1)]; a[i]=(p*p-(q*q).conj())*C(0,-0.25); } dft(a,n,-1); } int main(){ prework(); int n=read()+1,m=read()+1; For(i,0,n-1) a[i].r=read(); For(i,0,m-1) b[i].r=read(); int len=1; while (len<n+m-1) len*=2; mtt(a,b,len); For(i,0,n+m-2) printf("%d ",(int)(a[i].r+0.5)); puts(""); return 0; }
拆系数FFT
namespace poly{ const double pi=acos(-1.0); struct Comp{ double r,i; Comp(){} Comp(double _r,double _i){ r=_r,i=_i; } friend Comp operator + (Comp a,Comp b){ return Comp(a.r+b.r,a.i+b.i); } friend Comp operator - (Comp a,Comp b){ return Comp(a.r-b.r,a.i-b.i); } friend Comp operator * (Comp a,Comp b){ return Comp(a.r*b.r-a.i*b.i,a.i*b.r+a.r*b.i); } }a0[N],a1[N],b0[N],b1[N],A[N],B[N],C[N],w[N]; int R[N]; void FFT(Comp a[],int n){ for (int i=0;i<n;i++) if (i<R[i]) swap(a[i],a[R[i]]); for (int t=n>>1,d=1;d<n;d<<=1,t>>=1) for (int i=0;i<n;i+=d<<1) for (int j=0;j<d;j++){ Comp tmp=w[t*j]*a[i+j+d]; a[i+j+d]=a[i+j]-tmp; a[i+j]=a[i+j]+tmp; } } vector <int> Mul(vector <int> a,vector <int> b){ static vector <int> ans; ans.clear(); int n,d; for (n=1,d=0;n<a.size()+b.size();n<<=1,d++); for (int i=0;i<n;i++){ R[i]=(R[i>>1]>>1)|((i&1)<<(d-1)); w[i]=Comp(cos(pi*2/n*i),sin(pi*2/n*i)); } for (int i=0;i<n;i++) a0[i]=a1[i]=b0[i]=b1[i]=Comp(0,0); for (int i=0;i<a.size();i++) a0[i].r=a[i]&32767,a1[i].r=a[i]>>15; for (int i=0;i<b.size();i++) b0[i].r=b[i]&32767,b1[i].r=b[i]>>15; FFT(a0,n),FFT(a1,n),FFT(b0,n),FFT(b1,n); for (int i=0;i<n;i++){ A[i]=a0[i]*b0[i]; B[i]=a1[i]*b1[i]; C[i]=a0[i]*b1[i]+a1[i]*b0[i]; w[i].i=-w[i].i; } FFT(A,n),FFT(B,n),FFT(C,n); for (int i=0;i<n;i++){ int v=0; Add(v,(LL)(A[i].r/n+0.5)%mod); Add(v,(((LL)(B[i].r/n+0.5)%mod)<<30)%mod); Add(v,(((LL)(C[i].r/n+0.5)%mod)<<15)%mod); ans.pb(v); } while (!ans.empty()&&!ans.back()) ans.pop_back(); return ans; } }
求p的原根G(getg::calc(p))
namespace getg{ int power(int x,int y,int p){ int ans=1; for (;y;y>>=1,x=(LL)x*x%p) if (y&1) ans=(LL)ans*x%p; return ans; } int p; vector <int> v; int check(int g){ if (__gcd(g,p)!=1) return 0; for (auto i : v) if (power(g,(p-1)/i,p)==1) return 0; return 1; } int calc(int _p){ p=_p-1; v.clear(); for (int i=2;i*i<=p;i++) if (p%i==0){ v.push_back(i); while (p%i==0) p/=i; } if (p>1) v.push_back(p); p=_p; for (int g=1;g<p;g++) if (check(g)) return g; return -1; } }
$$n!mod P \ sum_{i=1}^{n} frac 1 i mod P\ P = 998244353$$
#include <bits/stdc++.h> #define clr(x) memset(x,0,sizeof (x)) #define For(i,a,b) for (int i=(a);i<=(b);i++) #define Fod(i,b,a) for (int i=(b);i>=(a);i--) #define fi first #define se second #define pb(x) push_back(x) #define mp(x,y) make_pair(x,y) #define outval(x) cerr<<#x" = "<<x<<endl #define outv(x) cerr<<#x" = "<<x<<" " #define outtag(x) cerr<<"--------------"#x"---------------"<<endl #define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = "; For(_x,L,R) cerr<<a[_x]<<" ";cerr<<endl; using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef unsigned uint; typedef long double LD; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=1<<19,mod=998244353; int Pow(int x,int y){ int ans=1; for (;y;y>>=1,x=(LL)x*x%mod) if (y&1) ans=(LL)ans*x%mod; return ans; } void Add(int &x,int y){ if ((x+=y)>=mod) x-=mod; } void Del(int &x,int y){ if ((x-=y)<0) x+=mod; } int Add(int x){ return x>=mod?x-mod:x; } int Del(int x){ return x<0?x+mod:x; } namespace fft{ int w[N],R[N]; void init(int n){ int d=0; while ((1<<d)<n) d++; For(i,0,n-1) R[i]=(R[i>>1]>>1)|((i&1)<<(d-1)); w[0]=1,w[1]=Pow(3,(mod-1)/n); For(i,2,n-1) w[i]=(LL)w[i-1]*w[1]%mod; } void FFT(int *a,int n,int flag){ For(i,0,n-1) if (i<R[i]) swap(a[i],a[R[i]]); for (int t=n>>1,d=1;d<n;d<<=1,t>>=1) for (int i=0;i<n;i+=d<<1) for (int j=0;j<d;j++){ int tmp=(LL)w[t*j]*a[i+j+d]%mod; a[i+j+d]=Del(a[i+j]-tmp); Add(a[i+j],tmp); } if (flag<0){ reverse(a+1,a+n); int inv=Pow(n,mod-2); For(i,0,n-1) a[i]=(LL)a[i]*inv%mod; } } vector <int> Mul(vector <int> a,vector <int> b){ int n=1,t=a.size()+b.size()-1; while (n<t) n<<=1; a.resize(n),b.resize(n); init(n); FFT(&a[0],n,1),FFT(&b[0],n,1); For(i,0,n-1) a[i]=(LL)a[i]*b[i]%mod; FFT(&a[0],n,-1); a.resize(t); return a; } } vector <int> calinv(vector <int> a){ static int pre[N]; int n=a.size()-1; pre[0]=1; For(i,1,n) pre[i]=(LL)pre[i-1]*a[i-1]%mod; int v=Pow(pre[n],mod-2); vector <int> b(n); Fod(i,n,1){ b[i-1]=(LL)v*pre[i-1]%mod; v=(LL)v*a[i-1]%mod; } return b; } int cal(vector <int> f,int x){ int v=1,ans=0; for (auto i : f) Add(ans,(LL)v*i%mod),v=(LL)v*x%mod; return ans; } int Fac[N],Inv[N],Iv[N]; void prework(){ int n=N-1; Fac[0]=1; For(i,1,n) Fac[i]=(LL)Fac[i-1]*i%mod; Inv[n]=Pow(Fac[n],mod-2); Fod(i,n,1) Inv[i-1]=(LL)Inv[i]*i%mod; For(i,1,n) Iv[i]=(LL)Inv[i]*Fac[i-1]%mod; } int bs; vector <int> cal0(vector <int> g){ int d=(int)g.size()-1; if (!d) return g; vector <int> a,b; a.resize(d+1); For(i,0,d){ a[i]=(LL)g[i]*Inv[i]%mod*Inv[d-i]%mod; if ((d-i)&1) a[i]=Del(-a[i]); } b.resize(d*2+1); b[0]=0; For(i,1,d*2) b[i]=Iv[i]; a=fft::Mul(a,b); a.resize(d*2+1); For(i,0,d) a[i]=g[i]; For(i,d+1,d*2) a[i]=(LL)a[i]*Fac[i]%mod*Inv[i-d-1]%mod; return a; } vector <int> cal1(vector <int> g){ int d=(int)g.size()-1; if (!d) return g; vector <int> a,b; int tmp=Pow(bs,mod-(d+1)); a.resize(d+1); For(i,0,d){ a[i]=(LL)g[i]*tmp%mod*Inv[i]%mod*Inv[d-i]%mod; if ((d-i)&1) a[i]=Del(-a[i]); } b.resize(d*3+1); For(i,0,d) b[i]=Pow(Add((LL)Del(i-d)*bs%mod+d),mod-2); For(i,1,d*2) b[i+d]=Pow(Add((LL)i*bs%mod+d),mod-2); a=fft::Mul(a,b); int v=1; For(i,0,d) v=(LL)v*Add(d+(LL)Del(-i)*bs%mod)%mod; For(i,0,d*2){ a[i+d]=(LL)a[i+d]*v%mod; v=(LL)v*Add(d+(LL)(i+1)*bs%mod)%mod *Pow(Add(d+(LL)Del(i-d)*bs%mod),mod-2)%mod; } For(i,0,d*2) a[i]=a[i+d]; a.resize(d*2+1); return a; } vector <int> Fac_super_double(vector <int> g){ int d=(int)g.size()-1; vector <int> a=cal0(g),b=cal1(g); For(i,0,d*2) a[i]=(LL)a[i]*b[i]%mod; return a; } int Fac_n(int n){ bs=max((int)sqrt(n),1)+1; vector <int> g(1,1); Fod(t,20,0){ g=Fac_super_double(g); if (bs>>t&1){ int d=(int)g.size(); For(i,0,d-1) g[i]=(LL)g[i]*(i*bs+d)%mod; int v=1; For(i,d*bs+1,d*bs+d) v=(LL)v*i%mod; g.pb(v); } } int t=0,ans=1; For(i,0,(int)g.size()-1) if (t+bs<=n) ans=(LL)ans*g[i]%mod,t+=bs; else break; For(i,t+1,n) ans=(LL)ans*i%mod; return ans; } void Har_super_double(vector <int> &g,vector <int> &f){ assert(g.size()==f.size()); int d=(int)g.size()-1; vector <int> g0=cal0(g),g1=cal1(g); vector <int> f0=cal0(f),f1=cal1(f); g.resize(d*2+1),f.resize(d*2+1); For(i,0,d*2){ g[i]=(LL)g0[i]*g1[i]%mod; f[i]=((LL)g0[i]*f1[i]+(LL)g1[i]*f0[i])%mod; } } int Har_n(int n){ bs=max((int)sqrt(n),1)+1; vector <int> g(1,1),f(1,0); Fod(t,20,0){ Har_super_double(g,f); if (bs>>t&1){ int d=(int)g.size(); For(i,0,d-1) f[i]=((LL)f[i]*(i*bs+d)+g[i])%mod; For(i,0,d-1) g[i]=(LL)g[i]*(i*bs+d)%mod; int v=1; For(i,d*bs+1,d*bs+d) v=(LL)v*i%mod; g.pb(v); v=0; For(i,d*bs+1,d*bs+d) Add(v,Pow(i,mod-2)); f.pb((LL)v*g[d]%mod); } } int t=0,ans=0; For(i,0,(int)g.size()-1) if (t+bs<=n) Add(ans,(LL)f[i]*Pow(g[i],mod-2)%mod),t+=bs; else break; For(i,t+1,n) Add(ans,Pow(i,mod-2)); return ans; } //namespace Test{ // int bFac_n(int n){ // int ans=1; // For(i,1,n) // ans=(LL)ans*i%mod; // return ans; // } // int bHar_n(int n){ // int ans=0; // For(i,1,n) // Add(ans,Pow(i,mod-2)); // return ans; // } // void main(){ // while (1){ // int n=read(); // int v=Har_n(n); // cout<<v<<endl; // assert(v==bHar_n(n)); // } // } //} int main(){ prework(); // Test::main(); return 0; }
KM (UOJ#80)
#include <bits/stdc++.h> #define clr(x) memset(x,0,sizeof (x)) using namespace std; typedef long long LL; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f|=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=405,INF=2e9; int n,m; int g[N][N]; void Getg(){ int c=read(); while (c--){ int x=read(),y=read(),z=read(); g[x][y]=z; } } int match[N],visx[N],visy[N],ex[N],ey[N],Min[N]; int dfs(int x){ visx[x]=1; for (int y=1;y<=m;y++) if (!visy[y]){ int d=ex[x]+ey[y]-g[x][y]; if (!d){ visy[y]=1; if (!match[y]||dfs(match[y])) return match[y]=x,1; } else Min[y]=min(Min[y],d); } return 0; } LL KM(){ clr(match),clr(ex),clr(ey); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) ex[i]=max(ex[i],g[i][j]); for (int i=1;i<=n;i++){ for (int j=1;j<=m;j++) Min[j]=INF; clr(visx),clr(visy); if (!dfs(i)){ while (1){ int d=INF,y=0; for (int j=1;j<=m;j++) if (!visy[j]) d=min(d,Min[j]); for (int j=1;j<=n;j++) if (visx[j]) ex[j]-=d; for (int j=1;j<=m;j++) if (visy[j]) ey[j]+=d; else if (!(Min[j]-=d)) y=j; if (!match[y]) break; int x=match[y]; visx[x]=visy[y]=1; for (int j=1;j<=m;j++) Min[j]=min(Min[j],ex[x]+ey[j]-g[x][j]); } clr(visx),clr(visy); assert(dfs(i)); } } LL ans=0; for (int i=1;i<=n;i++) ans+=ex[i]; for (int i=1;i<=m;i++) ans+=ey[i]; return ans; } int id[N]; int main(){ n=read(),m=max(n,(int)read()); Getg(); cout<<KM()<<endl; for (int i=1;i<=m;i++) id[match[i]]=i; for (int i=1;i<=n;i++) if (g[i][id[i]]) cout<<id[i]<<" "; else cout<<0<<" "; return 0; }
KMP
int Fail[N]; char S1[N],S2[N]; int KMP(string &s1,string &s2){ int n=s1.size(),m=s2.size(); for (int i=1;i<=n;i++) S1[i]=s1[i-1]; for (int i=1;i<=m;i++) S2[i]=s2[i-1]; Fail[0]=Fail[1]=0; for (int i=2;i<=m;i++){ int k=Fail[i-1]; while (k&&S2[i]!=S2[k+1]) k=Fail[k]; if (S2[i]==S2[k+1]) k++; Fail[i]=k; } int ans=0,k=0; for (int i=1;i<=n;i++){ while (k&&S1[i]!=S2[k+1]) k=Fail[k]; if (S1[i]==S2[k+1]) k++; if (k==m){ ans++; k=Fail[k]; } } return ans; }
Lucas
LL Lucas(LL n,LL m){ if (n<mod&&m<mod) return C(n,m); return C(n%mod,m%mod)*Lucas(n/mod,m/mod); }
Lyndon分解
vector <int> lyndon(char *s,int n){ //s[1..n] -> s[1..p1][p1+1..p2]... vector <int> res; for (int i=1;i<=n;){ int j=i,k=i+1; while (k<=n&&s[j]<=s[k]){ if (s[j]==s[k]) j++,k++; else if (s[j]<s[k]) j=i,k++; } while (i<=j){ i+=k-j; res.push_back(i-1); } } return res; }
NTT
namespace fft{ int w[N],rev[N]; void init(int n){ int d=0; while ((1<<d)<n) d++; w[0]=1,w[1]=Pow(3,(mod-1)/n); For(i,2,n-1) w[i]=(LL)w[i-1]*w[1]%mod; For(i,0,n-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(d-1)); } void dft(int *a,int n,int flag){ For(i,0,n-1) if (i<rev[i]) swap(a[i],a[rev[i]]); for (int t=n>>1,d=1;d<n;d<<=1,t>>=1) for (int i=0;i<n;i+=d<<1) For(j,0,d-1){ int tmp=(LL)a[i+j+d]*w[t*j]%mod; a[i+j+d]=Del(a[i+j]-tmp); a[i+j]=Add(a[i+j]+tmp); } if (flag<0){ reverse(a+1,a+n); int inv=Pow(n,mod-2); For(i,0,n-1) a[i]=(LL)a[i]*inv%mod; } } } using fft::dft;
NTT + 基础寻址优化
namespace fft{ int R[N]; vi w[23]; void prework(){ int d=log(N)/log(2)+0.5; For(i,1,d){ w[i].resize(1<<i); w[i][0]=1,w[i][1]=Pow(3,(mod-1)>>i); For(j,2,(1<<i)-1) w[i][j]=(LL)w[i][j-1]*w[i][1]%mod; } } void init(int n){ int d=0; while ((1<<d)<n) d++; For(i,0,n-1) R[i]=(R[i>>1]>>1)|((i&1)<<(d-1)); } void FFT(int *a,int n,int flag){ For(i,0,n-1) if (i<R[i]) swap(a[i],a[R[i]]); for (int t=1,d=1;d<n;d<<=1,t++) for (int i=0;i<n;i+=d<<1){ int *W=&w[t][0]; For(j,0,d-1){ int tmp=(LL)a[i+j+d]*(*W++)%mod; a[i+j+d]=Del(a[i+j]-tmp); a[i+j]=Add(a[i+j]+tmp); } } if (flag<0){ reverse(a+1,a+n); int inv=Pow(n,mod-2); For(i,0,n-1) a[i]=(LL)a[i]*inv%mod; } } }
MinRep 最小表示法
int MinRep(char *s,int n){ int i=1,j=2,k=0,t; while (i<=n&&j<=n&&k<n) (!(t=s[i+k>n?i+k-n:i+k]-s[j+k>n?j+k-n:j+k]))?(k++):((t>0?i:j)+=k+1,j+=(i==j),k=0); return min(i,j); }
int MinRep(char *s,int n){ #define _(x) ((x)>n?(x)-n:(x)) int i=1,j=2,k=0,t; while (i<=n&&j<=n&&k<n){ int t=t=s[_(i+k)]-s[_(j+k)]; if (t) (t>0?i:j)+=k+1,j+=(i==j),k=-1; k++; } #undef _ return min(i,j); }
(Updated 2019-03-25)
void Get_Min_Rep(char *s,int n){ static char tmp[N]; #define S(x) s[(x)>n?(x)-n:(x)] int i=1,j=2,k=0; while (i<=n&&j<=n&&k<n){ if (S(i+k)==S(j+k)) k++; else { (S(i+k)<S(j+k)?j:i)+=k+1; k=0; if (i==j) j++; } } int p=min(i,j); For(i,1,n) tmp[i]=S(p+i-1); For(i,1,n) s[i]=tmp[i]; #undef S }
Manachar (Updated on 2019-03-25)
int n; char s[N],ss[N]; int len[N]; void Manachar(char *s,int n){ For(i,0,n+1) len[i]=0; int mx=1; For(i,1,n){ len[i]=max(1,min(mx+len[mx]-i,len[mx*2-i])); while (s[i-len[i]]==s[i+len[i]]) len[i]++; if (i+len[i]>mx+len[mx]) mx=i; } } int solve(char *s,int n){ ss[0]='#',ss[1]='*'; For(i,1,n){ ss[i<<1]=s[i]; ss[i<<1|1]='*'; } ss[n*2+2]='$'; Manachar(ss,n*2+1); int ans=0; For(i,1,n*2+1) ans=max(ans,len[i]-1); return ans; }
PAM
namespace PAM{ int len[N],Fail[N],Next[N][26]; int size[N]; int cnt; void init(){ cnt=2; len[1]=-1,Fail[1]=1; len[2]=0,Fail[2]=1; clr(Next),clr(size); } void build(char *s,int n){ init(); s[0]='*'; int x=1; for (int i=1;i<=n;i++){ while (s[i-len[x]-1]!=s[i]) x=Fail[x]; int c=s[i]-'a'; if (Next[x][c]) x=Next[x][c]; else { int y=Next[x][c]=++cnt; len[y]=len[x]+2; if (len[y]==1) Fail[y]=2; else { x=Fail[x]; while (s[i-len[x]-1]!=s[i]) x=Fail[x]; Fail[y]=Next[x][c]; } x=y; } size[x]++; } for (int i=cnt;i>=1;i--) size[Fail[i]]+=size[i]; } }
Pollard_Rho
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef long double LD; namespace Pollard_Rho{ int prime[9]={2,3,5,7,11,13,17,19,23}; ULL RR; int Pcnt; LL p[70]; vector <LL> res; LL R(LL mod){ return (RR+=4179340454199820289LL)%mod; } LL Mul(LL x,LL y,LL mod){ LL d=(LL)floor((LD)x*y/mod+0.5); LL res=x*y-d*mod; if (res<0) res+=mod; return res; } LL Pow(LL x,LL y,LL mod){ LL ans=1%mod; for (;y;y>>=1,x=Mul(x,x,mod)) if (y&1) ans=Mul(ans,x,mod); return ans; } bool Miller_Rabin(LL n){ if (n<=1) return 0; for (int i=0;i<9;i++) if (n==prime[i]) return 1; LL d=n-1; int tmp=0; while (!(d&1)) d>>=1,tmp++; for (int i=0;i<9;i++){ LL x=Pow(prime[i],d,n),p=x; for (int j=1;j<=tmp;j++){ x=Mul(x,x,n); if (x==1&&p!=1&&p!=n-1) return 0; p=x; } if (x!=1) return 0; } return 1; } LL f(LL x,LL c,LL mod){ return (Mul(x,x,mod)+c)%mod; } LL gcd(LL x,LL y){ return y?gcd(y,x%y):x; } LL Get_Factor(LL c,LL n){ LL x=R(n),y=f(x,c,n),p=n; while (x!=y&&(p==n||p==1)){ p=gcd(n,max(x-y,y-x)); x=f(x,c,n); y=f(f(y,c,n),c,n); } return p; } void Pollard_Rho(LL n){ if (n<=1) return; if (Miller_Rabin(n)){ res.push_back(n); return; } while (1){ LL v=Get_Factor(R(n-1)+1,n); if (v!=n&&v!=1){ Pollard_Rho(v); Pollard_Rho(n/v); return; } } } void work(LL n){ res.clear(); Pollard_Rho(n); } } int main(){ LL n; scanf("%lld",&n); Pollard_Rho :: work(n); vector <LL> ans=Pollard_Rho :: res; sort(ans.begin(),ans.end()); printf("%d ",(int)ans.size()); for (int i=0;i<ans.size();i++) printf("%lld ",ans[i]); puts(""); return 0; }
SA (附带 ST 表查询区间 LCP )
int SA[N],rank[N],tmp[N],height[N],tax[N]; int ST[N][20]; void Sort(int n,int m){ for (int i=0;i<=m;i++) tax[i]=0; for (int i=1;i<=n;i++) tax[rank[i]]++; for (int i=1;i<=m;i++) tax[i]+=tax[i-1]; for (int i=n;i>=1;i--) SA[tax[rank[tmp[i]]]--]=tmp[i]; } bool cmp(int rk[],int x,int y,int w){ return rk[x]==rk[y]&&rk[x+w]==rk[y+w]; } void Suffix_Array(int s[],int n){ memset(SA,0,sizeof SA); memset(tmp,0,sizeof tmp); memset(rank,0,sizeof rank); memset(height,0,sizeof height); for (int i=1;i<=n;i++) rank[i]=s[i],tmp[i]=i; int m=234; Sort(n,m); for (int w=1,p=0;p<n;w<<=1,m=p){ p=0; for (int i=n-w+1;i<=n;i++) tmp[++p]=i; for (int i=1;i<=n;i++) if (SA[i]>w) tmp[++p]=SA[i]-w; Sort(n,m); swap(rank,tmp); rank[SA[1]]=p=1; for (int i=2;i<=n;i++) rank[SA[i]]=cmp(tmp,SA[i],SA[i-1],w)?p:++p; } for (int i=1,j,k=0;i<=n;height[rank[i++]]=k) for (k=max(k-1,0),j=SA[rank[i]-1];s[i+k]==s[j+k];k++); height[1]=0; } void Get_ST(int n){ memset(ST,0,sizeof ST); for (int i=1;i<=n;i++){ ST[i][0]=height[i]; for (int j=1;j<20;j++){ ST[i][j]=ST[i][j-1]; if (i-(1<<(j-1))>0) ST[i][j]=min(ST[i][j],ST[i-(1<<(j-1))][j-1]); } } } int Query(int L,int R){ int val=floor(log(R-L+1)/log(2)); return min(ST[L+(1<<val)-1][val],ST[R][val]); } int LCP(int x,int y){ x=rank[x],y=rank[y]; return Query(min(x,y)+1,max(x,y)); }
SAM
struct Node{ int Next[26],fa,Max; }t[N<<1]; int size,last; void init(){ size=last=1; } void extend(int c){ int p=last,np=++size,q,nq; t[np].Max=t[p].Max+1; for (;p&&!t[p].Next[c];p=t[p].fa) t[p].Next[c]=np; if (!p) t[np].fa=1; else { q=t[p].Next[c]; if (t[q].Max==t[p].Max+1) t[np].fa=q; else { nq=++size; t[nq]=t[q],t[nq].Max=t[p].Max+1; t[q].fa=t[np].fa=nq; for (;p&&t[p].Next[c]==q;p=t[p].fa) t[p].Next[c]=nq; } } last=np; }
SAM(广义)
struct SAM{ int Next[26],fa,Max; }t[N<<1]; int size; void init(){ memset(t,0,sizeof t); size=1,t[0].Max=-1; for (int i=0;i<26;i++) t[0].Next[i]=1; } int extend(int p,int c){ if (t[p].Next[c]&&t[p].Max+1==t[t[p].Next[c]].Max) return t[p].Next[c]; int np=++size,q,nq; t[np].Max=t[p].Max+1; for (;!t[p].Next[c];p=t[p].fa) t[p].Next[c]=np; q=t[p].Next[c]; if (t[p].Max+1==t[q].Max) t[np].fa=q; else { nq=++size; t[nq]=t[q],t[nq].Max=t[p].Max+1; t[q].fa=t[np].fa=nq; for (;t[p].Next[c]==q;p=t[p].fa) t[p].Next[c]=nq; } return np; }
求第一类 Stirling 数
namespace str{ vector <int> rpow[22]; //attention: rpow[i].size() = pow(2, n) + 1 //using: Fac[i] = i!, Inv[i] = 1/Fac[i]; mxd = pow(2, n) + 1 vector <int> Get_Add(vector <int> f,int n,int v){ vector <int> g,h; g.clear(); for (int i=-n;i<=0;i++) g.pb((LL)Pow(v,-i)*Inv[-i]%mod); for (int i=0;i<=n;i++) f[i]=(LL)f[i]*Fac[i]%mod; h=poly::Mul(f,g); while (h.size()<n*2+1) h.pb(0); g.clear(); for (int i=0;i<=n;i++) g.pb((LL)h[i+n]*Inv[i]%mod); return g; } vector <int> Get_rpow(int x){ if (!rpow[x].empty()) return rpow[x]; if (x==0){ rpow[x].pb(0),rpow[x].pb(1); return rpow[x]; } int n=1<<(x-1); vector <int> f=Get_rpow(x-1); rpow[x]=poly::Mul(f,Get_Add(f,n,n)); while (rpow[x].size()>n*2+1) rpow[x].pop_back(); while (rpow[x].size()<n*2+1) rpow[x].pb(0); return rpow[x]; } void Get_s1(int n,int res[]){ static vector <int> ans; if (n==0) return (void)(res[0]=1); ans.clear(); ans.pb(1); for (int i=0;i<20;i++) if (n>>i&1) ans=poly::Mul(Get_rpow(i),Get_Add(ans,(int)ans.size()-1,1<<i)); for (int i=0;i<=n;i++) res[i]=ans[i]; } }
ISAP (Updated in 2018-09-11)
#include <bits/stdc++.h> using namespace std; typedef long long LL; struct Edge{ int x,y,cap,nxt; Edge(){} Edge(int a,int b,int c,int d){ x=a,y=b,cap=c,nxt=d; } }; struct gragh{ static const int N=105,M=5005*2,INF=0x7fffffff; int n,S,T,fst[N],cnt; int dist[N],num[N],cur[N],p[N]; LL MaxFlow; Edge e[M]; void clear(int _n){ cnt=1,n=_n; memset(fst,0,sizeof fst); } void add(int a,int b,int c){ e[++cnt]=Edge(a,b,c,fst[a]),fst[a]=cnt; e[++cnt]=Edge(b,a,0,fst[b]),fst[b]=cnt; } void init(){ memset(dist,0,sizeof dist); memset(num,0,sizeof num); for (int i=1;i<=n;i++) num[dist[i]]++,cur[i]=fst[i]; } void init(int _S,int _T){ S=_S,T=_T; MaxFlow=0; init(); } int Augment(int &x){ int Flow=INF; for (int i=T;i!=S;i=e[p[i]].x) if (e[p[i]].cap<=Flow) Flow=e[p[i]].cap,x=e[p[i]].x; for (int i=T;i!=S;i=e[p[i]].x) e[p[i]].cap-=Flow,e[p[i]^1].cap+=Flow; return Flow; } LL ISAP(){ int x=S,y; while (dist[S]<n){ if (x==T){ MaxFlow+=Augment(x); continue; } bool found=0; for (int i=cur[x];i;i=e[i].nxt) if (dist[y=e[i].y]+1==dist[x]&&e[i].cap){ cur[x]=p[y]=i,x=y,found=1; break; } if (!found){ int d=n+1; for (int i=fst[x];i;i=e[i].nxt) if (e[i].cap) d=min(d,dist[e[i].y]+1); if (!--num[dist[x]]) return MaxFlow; num[dist[x]=d]++,cur[x]=fst[x],x=x==S?x:e[p[x]].x; } } return MaxFlow; } LL Auto(int _S,int _T){ init(_S,_T); return ISAP(); } }g;
Tarjan(有向图强联通分量)
int dfn[N],low[N],bh[N],st[N],inst[N],vis[N],Time,top,tot; void Tarjan_Prepare(){ Time=top=tot=0; memset(bh,0,sizeof bh); memset(st,0,sizeof st); memset(dfn,0,sizeof dfn); memset(low,0,sizeof low); memset(vis,0,sizeof vis); memset(inst,0,sizeof inst); } void Tarjan(int x){ dfn[x]=low[x]=++Time; inst[x]=vis[x]=1; st[++top]=x; for (int i=g.fst[x];i;i=g.nxt[i]) if (!vis[g.y[i]]){ Tarjan(g.y[i]); low[x]=min(low[x],low[g.y[i]]); } else if (inst[g.y[i]]) low[x]=min(low[x],low[g.y[i]]); if (dfn[x]==low[x]){ tot++; bh[st[top]]=tot; inst[st[top]]=0; while (st[top--]!=x){ bh[st[top]]=tot; inst[st[top]]=0; } } }
SPFA 费用流 (Updated on 2018-09-12)
#include <bits/stdc++.h> using namespace std; typedef long long LL; struct Edge{ int x,y,c,nxt,cap; Edge(){} Edge(int a,int b,int _c,int d,int e){ x=a,y=b,c=_c,cap=d,nxt=e; } }; struct Network{ static const int N=405,M=15005*2,INF=0x7FFFFFFF; Edge e[M]; int n,S,T,fst[N],cur[N],cnt; int q[N],vis[N],head,tail; int MaxFlow,MinCost,dis[N]; void clear(int _n){ n=_n,cnt=1; memset(fst,0,sizeof fst); } void add(int a,int b,int c,int d){ e[++cnt]=Edge(a,b,d,c,fst[a]),fst[a]=cnt; e[++cnt]=Edge(b,a,-d,0,fst[b]),fst[b]=cnt; } void init(){ for (int i=1;i<=n;i++) cur[i]=fst[i]; } void init(int _S,int _T){ S=_S,T=_T,MaxFlow=MinCost=0,init(); } int SPFA(){ for (int i=1;i<=n;i++) dis[i]=INF; memset(vis,0,sizeof vis); head=tail=0; dis[q[++tail]=T]=0; while (head!=tail){ if ((++head)>=n) head-=n; int x=q[head]; vis[x]=0; for (int i=fst[x];i;i=e[i].nxt){ int y=e[i].y; if (e[i^1].cap&&dis[x]-e[i].c<dis[y]){ dis[y]=dis[x]-e[i].c; if (!vis[y]){ if ((++tail)>=n) tail-=n; vis[q[tail]=y]=1; } } } } memset(vis,0,sizeof vis); return dis[S]<INF; } int dfs(int x,int Flow){ if (x==T||!Flow) return Flow; vis[x]=1; int now=Flow; for (int &i=cur[x];i;i=e[i].nxt){ int y=e[i].y; if (!vis[y]&&e[i].cap&&dis[x]-e[i].c==dis[y]){ int d=dfs(y,min(now,e[i].cap)); e[i].cap-=d,e[i^1].cap+=d; if (!(now-=d)) break; } } vis[x]=0; return Flow-now; } void Dinic(){ while (SPFA()){ init(); int now=dfs(S,INF); MaxFlow+=now,MinCost+=now*dis[S]; } } void MCMF(int &_MinCost,int &_MaxFlow){ Dinic(),_MinCost=MinCost,_MaxFlow=MaxFlow; } void Auto(int _S,int _T,int &_MinCost,int &_MaxFlow){ init(_S,_T),MCMF(_MinCost,_MaxFlow); } }g; int read(){ int x=0; char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return x; } int n,m,S,T; int main(){ n=read(),m=read(),S=1,T=n; g.clear(n); while (m--){ int a=read(),b=read(),c=read(),cap=read(); g.add(a,b,c,cap); } int MinCost,MaxFlow; g.Auto(S,T,MinCost,MaxFlow); printf("%d %d ",MaxFlow,MinCost); return 0; }
主席树 - 二维数点
int root[N],sum[S],ls[S],rs[S],tot=0; void build(int &rt,int L,int R){ sum[rt=++tot]=0; if (L==R) return; int mid=(L+R)>>1; build(ls[rt],L,mid); build(rs[rt],mid+1,R); } void update(int prt,int &rt,int L,int R,int x){ if (!rt||rt==prt) sum[rt=++tot]=sum[prt]; sum[rt]++; if (L==R) return; if (!ls[rt]) ls[rt]=ls[prt]; if (!rs[rt]) rs[rt]=rs[prt]; int mid=(L+R)>>1; if (x<=mid) update(ls[prt],ls[rt],L,mid,x); else update(rs[prt],rs[rt],mid+1,R,x); } int query(int rt,int L,int R,int xL,int xR){ if (!rt||R<xL||L>xR) return 0; if (xL<=L&&R<=xR) return sum[rt]; int mid=(L+R)>>1; return query(ls[rt],L,mid,xL,xR)+query(rs[rt],mid+1,R,xL,xR); } int Query(int x1,int x2,int y1,int y2){ return query(root[x2],1,yt,y1,y2)-query(root[x1-1],1,yt,y1,y2); }
最小圆覆盖
#pragma GCC optimize("Ofast","inline") #include <bits/stdc++.h> #define clr(x) memset(x,0,sizeof (x)) #define outval(x) printf(#x" = %d ",x) #define For(x,a,b) for (int x=a;x<=b;x++) #define Fod(x,b,a) for (int x=b;x>=a;x--) #define pb push_back using namespace std; typedef long long LL; LL read(){ LL x=0,f=0; char ch=getchar(); while (!isdigit(ch)) f|=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } const int N=500005; const double Eps=1e-9,pi=acos(-1.0); struct Point{ double x,y; Point(){} Point(double _x,double _y){ x=_x,y=_y; } }p[N]; int Dcmp(double x){ if (fabs(x)<Eps) return 0;return x<0?-1:1; } int Dcmp(double x,double y){ return Dcmp(x-y); } Point operator + (Point A,Point B){ return Point(A.x+B.x,A.y+B.y); } Point operator - (Point A,Point B){ return Point(A.x-B.x,A.y-B.y); } Point operator * (Point A,double x){ return Point(A.x*x,A.y*x); } Point operator / (Point A,double x){ return Point(A.x/x,A.y/x); } Point Rotate(Point A,double B){ return Point(A.x*cos(B)-A.y*sin(B),A.x*sin(B)+A.y*cos(B)); } double cross(Point A,Point B){ return A.x*B.y-A.y*B.x; } double cross(Point A,Point B,Point C){ return cross(B-A,C-A); } double Dot(Point A,Point B){ return A.x*B.x+A.y*B.y; } double Dis(Point A,Point B){ return sqrt(Dot(A-B,A-B)); } Point Center(Point A,Point B,Point C){ Point a=(A+B)/2,b=(A+C)/2; Point u=Rotate(B-A,pi/2),v=Rotate(C-A,pi/2); if (Dcmp(cross(u,v))==0){ if (Dcmp(Dis(A,C),Dis(A,B)+Dis(B,C))==0) return (A+C)/2; if (Dcmp(Dis(A,B),Dis(A,C)+Dis(B,C))==0) return (A+B)/2; if (Dcmp(Dis(B,C),Dis(A,B)+Dis(A,C))==0) return (B+C)/2; } return a+u*cross(v,a-b)/cross(u,v); } int n; int main(){ srand(233); n=read(); for (int i=1;i<=n;i++) p[i].x=read(),p[i].y=read(); Point c=p[1]; double r=0; random_shuffle(p+1,p+n+1); for (int i=2;i<=n;i++){ if (Dcmp(Dis(p[i],c),r)<=0) continue; c=p[i],r=0; for (int j=1;j<i;j++){ if (Dcmp(Dis(p[j],c),r)<=0) continue; c=(p[i]+p[j])/2,r=Dis(p[i],c); for (int k=1;k<j;k++){ if (Dcmp(Dis(p[k],c),r)<=0) continue; c=Center(p[i],p[j],p[k]); r=Dis(p[i],c); } } } printf("%.6lf %.6lf %.6lf ",r,c.x,c.y); return 0; }
Splay - BZOJ3224
#include <bits/stdc++.h> using namespace std; const int N=100005; int n,root=1,size=1,val[N],cnt[N],son[N][2],fa[N],tot[N]; int wson(int x){ return son[fa[x]][1]==x; } void pushup(int x){ tot[x]=cnt[x]+tot[son[x][0]]+tot[son[x][1]]; } void rotate(int x){ if (!x) return; int y=fa[x],z=fa[y],L=wson(x),R=L^1; if (z) son[z][wson(y)]=x; fa[x]=z,fa[y]=x,fa[son[x][R]]=y; son[y][L]=son[x][R],son[x][R]=y; pushup(y),pushup(x); } void splay(int x,int k){ if (!x) return; if (!k) root=x; for (int y=fa[x];fa[x]!=k;rotate(x),y=fa[x]) if (fa[y]!=k) rotate(wson(x)==wson(y)?y:x); } int find(int x,int v){ return val[x]==v?x:find(son[x][v>val[x]],v); } int findkth(int x,int k){ if (k<=tot[son[x][0]]) return findkth(son[x][0],k); k-=tot[son[x][0]]; if (k<=cnt[x]) return x; k-=cnt[x]; return findkth(son[x][1],k); } int findnxt(int x,int v){ if (!x) return 0; if (val[x]<=v) return findnxt(son[x][1],v); else { int res=findnxt(son[x][0],v); return res?res:x; } } int findpre(int x,int v){ if (!x) return 0; if (val[x]>=v) return findpre(son[x][0],v); else { int res=findpre(son[x][1],v); return res?res:x; } } void insert(int &x,int pre,int v){ if (!x){ x=++size; val[x]=v,cnt[x]=tot[x]=1,fa[x]=pre; splay(x,0); return; } tot[x]++; if (val[x]==v){ cnt[x]++; return; } insert(son[x][v>val[x]],x,v); } void Insert(int v){insert(root,0,v);} void Delete(int v){ int x; splay(x=find(root,v),0); if (--cnt[x]) return; splay(findnxt(root,v),root); root=son[x][1]; son[root][0]=son[x][0]; fa[son[x][0]]=root; fa[root]=son[x][0]=son[x][1]=0; pushup(root); } int Rank(int v){ splay(find(root,v),0); return tot[son[root][0]]+1; } int main(){ val[1]=2147483647; cnt[1]=tot[1]=1; scanf("%d",&n); while (n--){ int opt,x; scanf("%d%d",&opt,&x); if (opt==1) Insert(x); if (opt==2) Delete(x); if (opt==3) printf("%d ",Rank(x)); if (opt==4) printf("%d ",val[findkth(root,x)]); if (opt==5) printf("%d ",val[findpre(root,x)]); if (opt==6) printf("%d ",val[findnxt(root,x)]); } return 0; }
匈牙利算法
int g[N][N],vis[N],match[N]; bool Match(int x){ for (int i=1;i<=n;i++) if (!vis[i]&&g[x][i]){ vis[i]=1; if (!match[i]||Match(match[i])){ match[i]=x; return 1; } } return 0; } int hungary(){ int res=0; memset(match,0,sizeof match); for (int i=1;i<=n;i++){ memset(vis,0,sizeof vis); if (Match(i)) res++; } return res; }
高精度整数运算 (由于懒和菜,没有更新带 FFT 的乘法和快速的除法)(UPD2020-08-10:这个模板可能有锅?(尽管它能过很多高精度模板题))
支持负数
#include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) using namespace std; typedef long long LL; /* 大数模板8 1. 支持大数之间的+、-、*、/、%运算,以及一些基础的计算 2. 支持部分大数与整型之间的运算 (仅限于大数在前整型在后) +、-、*、/、% 3. 支持负数的运算,不会出现减法的时候由于被减数小于减数所造成的报错。 4. 快速幂,代码优化 5. 可以进行正常的比较。 6. 新增 abs(), read()两个方便的函数 read() 具体用法 1. read('c',Var_Name<BigInt>) 读入一个char数组类型转化而来的大数 2. read('i',Var_Name<BigInt>) 读入一个int类型转化而来的大数 3. read('L',Var_Name<BigInt>) 读入一个long long类型转化而来的大数 7. 修复原先模板中关于0的bug 8. 新增构造函数 9. 修复若干bug,新增一些功能 10. progress: 9位压位,大大提高效率 *///版权所有--周镇东 const int MaxLen=1200; const LL mod=1e9; const LL Pow10[9]={1e0,1e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8}; struct BigInt{ LL d,v[MaxLen+5]; bool f;//保存正负性 ,0当作正数看待 BigInt (){} BigInt (LL x){(*this)=x;} BigInt (int x){(*this)=x;} BigInt (char x[]){(*this)=x;} BigInt (const BigInt &x){(*this)=x;} void Print(){ if (f) putchar('-'); if (d==0){ putchar('0'); return; } printf("%lld",v[d]); for (int i=d-1;i>=1;i--) printf("%09lld",v[i]); } void Print(char c){//输出数字 (*this).Print(); printf("%c",c); } void ya(){ LL v_[MaxLen]; memset(v_,0,sizeof v_); for (int i=1;i<=d;i++) v_[(i-1)/9+1]+=Pow10[(i-1)%9]*v[i]; d=(d-1)/9+1; memset(v,0,sizeof v); for (int i=1;i<=d;i++) v[i]=v_[i]; while (d>0&&v[d]==0) d--; } void operator =(char x[]){ f=x[0]=='-',d=strlen(x)-f,memset(v,0,sizeof v); for (int i=f;i<d+f;i++) v[i-f+1]+=(x[d+f-(i-f)-1]-48); while (d>0&&v[d]==0) d--; (*this).ya(); } void operator =(int x){ (*this)=(LL)x; } void operator =(LL x){ d=0,f=x<0,x=abs(x); memset(v,0,sizeof v); while (x) v[++d]=x%mod,x/=mod; } bool equ(BigInt &x){//cmp abs if (d!=x.d) return 0; for (int i=1;i<=d;i++) if (v[i]!=x.v[i]) return 0; return 1; } bool operator ==(BigInt &x){//cmp abs if (f!=x.f) return 0; return (*this).equ(x); } bool nequ(BigInt &x){ return !(*this).equ(x); } bool operator !=(BigInt &x){ return !(*this==x); } bool smaller(BigInt &x){ if (d!=x.d) return d<x.d; for (int i=d;i>=1;i--) if (v[i]!=x.v[i]) return v[i]<x.v[i]; return 0; } bool bigger(BigInt &x){ if (d!=x.d) return d>x.d; for (int i=d;i>=1;i--) if (v[i]!=x.v[i]) return v[i]>x.v[i]; return 0; } bool operator <(BigInt &x){//cmp abs if (f!=x.f) return f; if (f&&x.f) return (*this).bigger(x); return (*this).smaller(x); } bool operator >(BigInt &x){ if (f!=x.f) return x.f; if (f&&x.f) return (*this).smaller(x); return (*this).bigger(x); } bool smqu(BigInt &x){ return !(*this).bigger(x); } bool bgqu(BigInt &x){ return !(*this).smaller(x); } bool operator <=(BigInt &x){ return !(*this>x); } bool operator >=(BigInt &x){ return !(*this<x); } BigInt operator +(BigInt x){//加法运算 BigInt Ans=*this; if (f!=x.f){ Ans.f=x.f=0; if (f) return x-Ans; else return Ans-x; } memset(Ans.v,0,sizeof Ans.v); Ans.f=f,Ans.d=max(d,x.d); for (int i=1;i<=Ans.d;i++) Ans.v[i]=v[i]+x.v[i]; for (int i=1;i<=Ans.d;i++) Ans.v[i+1]+=Ans.v[i]/mod,Ans.v[i]%=mod; if (Ans.v[Ans.d+1]) Ans.d++; if (Ans.d==0) Ans.f=0; return Ans; } BigInt operator +(const LL x){ BigInt X(x); return X+(*this); } BigInt operator -(BigInt y){//减法运算 BigInt Ans=*this; if (f!=y.f){ y.f=Ans.f,Ans=Ans+y; return Ans; } if (Ans.equ(y)){ Ans=0; return Ans; } if (Ans.smaller(y)){ Ans=y-Ans,Ans.f=!f; return Ans; } for (int i=1;i<=max(Ans.d,y.d);i++) if (Ans.v[i]-y.v[i]<0) Ans.v[i]+=mod-y.v[i],Ans.v[i+1]--; else Ans.v[i]-=y.v[i]; while (Ans.d>0&&Ans.v[Ans.d]==0) Ans.d--; if (Ans.d==0) Ans.f=0; return Ans; } BigInt operator -(const LL x){ BigInt Ans(x); return (*this)-Ans; } BigInt operator *(const BigInt &y){//乘法运算 BigInt x=*this,Ans(0); Ans=0,Ans.f=f^y.f; for (int i=1;i<=x.d;i++) for (int j=1;j<=y.d;j++){ LL now=Ans.v[i+j-1]+x.v[i]*y.v[j]; Ans.v[i+j-1]=now%mod; Ans.v[i+j]+=now/mod; } Ans.d=x.d+y.d-1; for (int i=1;i<=Ans.d;i++) Ans.v[i+1]+=Ans.v[i]/mod,Ans.v[i]%=mod; if (Ans.v[Ans.d+1]) Ans.d++; if (Ans.d==0) Ans.f=0; return Ans; } BigInt operator *(LL y){ BigInt Ans=*this; if (y<0) Ans.f^=1; y=abs(y); for (int i=1;i<=d;i++) Ans.v[i]*=y; for (int i=1;i<=d||Ans.v[i]>0;i++) Ans.v[i+1]+=Ans.v[i]/mod,Ans.v[i]%=mod,Ans.d=max(d,i); if (Ans.d==0) Ans.f=0; return Ans; } BigInt operator /(BigInt y){//除法运算 BigInt Ans(0),x=*this,minus; bool Ansf=f^y.f; x.f=y.f=0,minus=y; while ((minus*10).smqu(x)) minus=minus*10; while (minus.bgqu(y)){ Ans=Ans*10; while (minus.smqu(x)) x=x-minus,Ans=Ans+1; minus=minus/10; } Ans.f=Ansf; if (Ans.d==0) Ans.f=0; return Ans; } BigInt operator /(LL x){ BigInt Ans(0); LL prev=0; Ans.f=f^(x<0),Ans.d=0,x=abs(x); for (int i=d;i>0;i--){ prev=prev*mod+v[i]; if (prev>=x) Ans.v[i]=prev/x,prev%=x,Ans.d=max(Ans.d,i); } if (Ans.d==0) Ans.f=0; return Ans; } BigInt operator %(BigInt y){//取模运算 BigInt x=*this,minus; bool xfz=f^y.f; x.f=y.f=0,minus=y; if (x<y){ x.f=xfz; return x; } while ((minus*10).smqu(x)) minus=minus*10; while (minus.bgqu(y)){ while (minus.smqu(x)) x=x-minus; minus=minus/10; } x.f=xfz; if (x.d==0) x.f=0; return x; } LL operator %(LL x){ LL prev=0; bool flag=f^(x<0); x=abs(x); for (int i=d;i>0;i--) prev=prev*mod+v[i],prev%=x; if (flag) prev=-prev; return prev; } BigInt operator ^(int x){ BigInt Ans; Ans=1; if (x==0) return Ans; Ans=*this^(x/2); Ans=Ans*Ans; if (x&1) Ans=Ans**this; return Ans; } }zero(0),one(1); BigInt GcdY(BigInt x,BigInt y){ return y!=zero?GcdY(y,x%y):x; } BigInt Gcd(BigInt x,BigInt y){ x.f=y.f=0; if (x==zero) return y; if (y==zero) return x; return GcdY(x,y); } BigInt LcmY(BigInt x,BigInt y){ return x/GcdY(x,y)*y; } BigInt Lcm(BigInt x,BigInt y){ x.f=y.f=0; if (x==zero) return y; if (y==zero) return x; return LcmY(x,y); } BigInt abs(BigInt x){ x.f=0; return x; } void read(char ch,BigInt &x){ if (ch=='c'){ char str[MaxLen]; scanf("%s",str),x=str; } if (ch=='i'){ int y; scanf("%d",&y),x=y; } if (ch=='L'){ LL y; scanf("%lld",&y),x=y; } } void readint(BigInt &x,int &ret){ scanf("%d",&ret),x=ret; } void readLL(BigInt &x,LL &ret){ scanf("%lld",&ret),x=ret; } int main(){ BigInt A,B; LL a,b; readLL(A,a),readLL(B,b); A.Print(' '); B.Print(' '); // read('c',A),read('c',B); A.Print(' '); B.Print(' '); printf("Gcd(A,B)=");Gcd(A,B).Print(' '); A.Print(' '); B.Print(' '); printf("Lcm(A,B)=");Lcm(A,B).Print(' '); A.Print(' '); B.Print(' '); printf("A*B=");(A*B).Print(' '); A.Print(' '); B.Print(' '); printf("A-B=");(A-B).Print(' '); A.Print(' '); B.Print(' '); printf("A+B=");(A+B).Print(' '); A.Print(' '); B.Print(' '); printf("A/B=");(A/B).Print(' '); A.Print(' '); B.Print(' '); // printf("A/b=");(A/b).Print(' '); A.Print(' '); B.Print(' '); // printf("A^b=");(A^b).Print(' '); A.Print(' '); B.Print(' '); // printf("A*b=");(A*b).Print(' '); A.Print(' '); B.Print(' '); // printf("A+b=");(A+b).Print(' '); A.Print(' '); B.Print(' '); // printf("A-b=");(A-b).Print(' '); A.Print(' '); B.Print(' '); // printf("A%b=");printf("%d ",A%b); A.Print(' '); B.Print(' '); printf("A%B=");(A%B).Print(' '); A.Print(' '); B.Print(' '); printf("A<B?->");printf("%d ",A<B); A.Print(' '); B.Print(' '); printf("A>B?->");printf("%d ",A>B); A.Print(' '); B.Print(' '); printf("A<=B?->");printf("%d ",A<=B); A.Print(' '); B.Print(' '); printf("A>=B?->");printf("%d ",A>=B); A.Print(' '); B.Print(' '); printf("A==B?->");printf("%d ",A==B); A.Print(' '); B.Print(' '); printf("A!=B?->");printf("%d ",A!=B); A.Print(' '); B.Print(' '); printf("abs(A)=");abs(A).Print(' '); A.Print(' '); B.Print(' '); printf("abs(B)=");abs(B).Print(' '); A.Print(' '); B.Print(' '); printf(" 优先级判断: "); A.Print(' '); B.Print(' '); printf("A*B^2=");(A*B^2).Print(' '); A.Print(' '); B.Print(' ');//ans:A*B^2=(A*B)^2 printf("A/A*B=");(A/A*B).Print(' '); A.Print(' '); B.Print(' ');//ans:A/A*B=B return 0; }
高精度分数运算(基于上一份高精度整数运算)
struct BigDouble{ BigInt a,b; void Print(){ (*this).Smaller(); if (a==zero){ printf("0"); return; } if (b==one) a.Print(); else a.Print('/'),b.Print(); } void Print(char ch){ (*this).Smaller(); if (a==zero){ printf("0%c",ch); return; } if (b==one) a.Print(ch); else a.Print('/'),b.Print(ch); } void Smaller(){ if (a==zero||b==zero) return; // a.Print(' ');b.Print(' '); BigInt gcd=Gcd(a,b); // puts("Small achieve"); a=a/gcd,b=b/gcd; // puts("div adchive"); if (b.f) a.f^=1,b.f^=1; } void operator = (BigInt x){ a=x,b=one; } BigDouble operator * (BigDouble x){ BigDouble ans; ans.a=a*x.a,ans.b=b*x.b; ans.Smaller(); return ans; } BigDouble operator * (BigInt x){ BigDouble ans; ans.a=x*a,ans.b=b; ans.Smaller(); return ans; } BigDouble operator - (BigDouble x){ BigDouble ans; BigInt lcm=Lcm(b,x.b),tt=lcm/b,tx=lcm/x.b; // BigInt lcm=one,tt=one,tx=one; ans.b=lcm,ans.a=a*tt-x.a*tx; ans.Smaller(); return ans; } BigDouble operator / (BigInt x){ BigDouble ans; // b.Print(' ');x.Print(' '); ans.a=a,ans.b=b*x; // puts("still alive"); ans.Smaller(); return ans; } BigDouble operator / (BigDouble x){ BigDouble ans; ans.a=a*x.b,ans.b=b*x.a; ans.Smaller(); return ans; } }x[N];
Topcoder 模板
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; class $CLASSNAME${ public: $RC$ $METHODNAME$($METHODPARMS$){ } $TESTCODE$ }; $BEGINCUT$ int main(){ $CLASSNAME$ ___test; ___test.run_test(-1); return 0; } $ENDCUT$ TopCoder Template
Adblock-Plus 配置
blog.csdn.net##.recommend-item-box.recommend-box-ident.type_blog.clearfix blog.csdn.net##.right_box.footer_box.csdn-tracking-statistics blog.csdn.net##.recommend-item-box.recommend-box-ident.recommend-download-box.clearfix blog.csdn.net##.recommend-item-box.recommend-ad-box blog.csdn.net##.recommend-item-box.blog-expert-recommend-box blog.csdn.net##.recommend-item-box.type_hot_word blog.csdn.net##.pulllog-box blog.csdn.net##.meau-list blog.csdn.net###reportContent blog.csdn.net##.btn-meau blog.csdn.net##.showBig.animated.bounceInRight blog.csdn.net##.btn-close-ad blog.csdn.net##.recommend-item-box.baiduSearch blog.csdn.net##.mediav_ad blog.csdn.net###csdn-toolbar blog.csdn.net##.csdn-toolbar.tb_disnone blog.csdn.net##.aside-title blog.csdn.net##.aside-content.clearfix blog.csdn.net##.aside-content ||pos.baidu.com/fcpm?conwid=300&conhei=250&rdid=3032528&dc=3&exps=110011&psi=3804dbd7f0cda1b989b5fada13af8a2f&di=u3032528&dri=0&dis=0&dai=3&ps=328x101&enu=encoding&dcb=___adblockplus&dtm=HTML_POST&dvi=0.0&dci=-1&dpt=none&tsr=0&tpr=1550628280860&ti=bzoj1001%5B%E7%8B%BC%E7%88%AA%E5%85%94%E5%AD%90%5D%E6%9C%80%E5%B0%8F%E5%89%B2%E8%BD%AC%E6%9C%80%E7%9F%AD%E8%B7%AF%20-%20nikelong%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&ari=2&dbv=2&drs=1&pcs=1520x730&pss=1520x1381&cfv=0&cpl=2&chi=1&cce=true&cec=UTF-8&tlm=1550628281&prot=2&rw=730<u=https%3A%2F%2Fblog.csdn.net%2Fnikelong0%2Farticle%2Fdetails%2F50727840<r=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DtXeCtlFHKSI-g80lHRJJU5wQQTLkRXwzB9I_1Yv55g1AELHBDINXkK7We0Q8oyGYd8I_1w9_NJEIVWJPc4VB7c77R35Xvq6ZKjliEwJH_dK%26wd%3D%26eqid%3Da9c9876500035954000000045c6cb5b6&ecd=1&uc=1535x876&pis=-1x-1&sr=1600x900&tcn=1550628281&qn=c1321737e08fd10c&tt=1550628280838.463.464.472 ||ubmcmm.baidustatic.com/media/v1/0f000ji9GQBTQif4KlS1n6.jpg ||ubmcmm.baidustatic.com/media/v1/0f000Dd29O15Im4ZGHXmF0.jpg ||pos.baidu.com/fcpm?conwid=300&conhei=250&rdid=3163270&dc=3&exps=110011&psi=3804dbd7f0cda1b989b5fada13af8a2f&di=u3163270&dri=0&dis=0&dai=4&ps=2124x101&enu=encoding&dcb=___adblockplus&dtm=HTML_POST&dvi=0.0&dci=-1&dpt=none&tsr=0&tpr=1550628280860&ti=bzoj1001%5B%E7%8B%BC%E7%88%AA%E5%85%94%E5%AD%90%5D%E6%9C%80%E5%B0%8F%E5%89%B2%E8%BD%AC%E6%9C%80%E7%9F%AD%E8%B7%AF%20-%20nikelong%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2&ari=2&dbv=2&drs=1&pcs=1520x730&pss=1520x2124&cfv=0&cpl=2&chi=1&cce=true&cec=UTF-8&tlm=1550628281&prot=2&rw=730<u=https%3A%2F%2Fblog.csdn.net%2Fnikelong0%2Farticle%2Fdetails%2F50727840<r=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DtXeCtlFHKSI-g80lHRJJU5wQQTLkRXwzB9I_1Yv55g1AELHBDINXkK7We0Q8oyGYd8I_1w9_NJEIVWJPc4VB7c77R35Xvq6ZKjliEwJH_dK%26wd%3D%26eqid%3Da9c9876500035954000000045c6cb5b6&ecd=1&uc=1535x876&pis=-1x-1&sr=1600x900&tcn=1550628281&qn=4c64b7f9f4152e7f&tt=1550628280838.552.552.554
Ublock 配置
! 2/20/2019 https://blog.csdn.net blog.csdn.net##.box-shadow.mb8.csdn-tracking-statistics blog.csdn.net###asideHotArticle > .aside-content blog.csdn.net###asideCategory > .text-center blog.csdn.net###asideArchive > .text-center ! 2018/10/28 下午12:34:10 https://blog.csdn.net/forever_shi/article/details/83109712 blog.csdn.net###asideArchive > .text-center ! 2018/10/28 下午12:35:08 https://blog.csdn.net/forever_shi/article/details/83109712 blog.csdn.net##.d-flex.badge-box ! 2018/10/28 下午12:35:12 https://blog.csdn.net/forever_shi/article/details/83109712 blog.csdn.net###asideCategory > .text-center ! 2018/10/28 下午12:35:17 https://blog.csdn.net/forever_shi/article/details/83109712 blog.csdn.net##.meau-list > li:nth-of-type(2) ! 2018/10/28 下午12:35:21 https://blog.csdn.net/forever_shi/article/details/83109712 blog.csdn.net##.meau-list > li:nth-of-type(3) ! 2018/10/28 下午12:35:31 https://blog.csdn.net/forever_shi/article/details/83109712 blog.csdn.net###btnAttent ! 2018/10/28 下午3:16:50 https://www.baidu.com/ www.baidu.com##.qrcodeCon ! 2018/10/28 下午3:16:54 https://www.baidu.com/ www.baidu.com##.ftCon-Wrapper ! 2018/10/28 下午3:16:59 https://www.baidu.com/ www.baidu.com###ftCon ! 2018/10/28 下午3:17:04 https://www.baidu.com/ www.baidu.com###u1 ! 2018/10/28 下午3:17:34 https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=bzoj1117&rsv_pq=f8dd55a00004d7ff&rsv_t=193aOBVWE2eZF6R2NN3h0DU7J8Gd8a3U%2FRiSF1tHowxIyesTo4%2B4In05Au0&rqlang=cn&rsv_enter=1&rsv_sug3=8&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&inputT=3603&rsv_sug4=3603 www.baidu.com###content_right ! 2018/10/28 下午4:33:48 https://blog.csdn.net/ocgcn2010/article/details/50939261?fps=1&locationNum=9 blog.csdn.net##.clearfix.t0 ! 2018/10/28 下午6:24:05 https://blog.csdn.net/clover_hxy/article/details/53834702 blog.csdn.net##div.recommend-item-box:nth-of-type(20) ! 2018/10/28 下午6:26:00 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html ||simg.sinajs.cn/blog7newtpl/image/30/30_4/images/sg_newsp.png$image ! 2018/10/28 下午6:26:07 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html blog.sina.com.cn##.turnBoxzz > .SG_turn.SG_aBtn_ico.SG_aBtn > cite ! 2018/10/28 下午6:27:10 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html blog.sina.com.cn##.formBtn ! 2018/10/28 下午6:27:15 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html blog.sina.com.cn##.writeComm ! 2018/10/28 下午6:27:21 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html blog.sina.com.cn##.SG_floatR > .SG_txtb ! 2018/10/28 下午6:27:52 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html ||simg.sinajs.cn/blog7style/images/common/btn_share.png$image ! 2018/10/28 下午6:27:56 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html blog.sina.com.cn##.SG_txtb.share > span ! 2018/10/28 下午6:28:00 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html ||simg.sinajs.cn/blog7style/images/common/multishow_bg.png$image ! 2018/10/28 下午6:28:05 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html blog.sina.com.cn##.picSlideBtn > [href="javascript:void(0);"] ! 2018/10/28 下午6:28:14 http://blog.sina.com.cn/s/blog_8f06da99010125ol.html ||sjs.sinajs.cn/blog7swf/lookViewSpring.swf?2$object ! 2018/10/28 下午6:29:28 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com###activity-tg ! 2018/10/28 下午6:29:45 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com###activity-tg ! 2018/10/28 下午6:30:09 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.reader-backToTop ! 2018/10/28 下午6:30:16 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com###activity-tg ! 2018/10/28 下午6:30:30 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.notvip-book.side-a.novip.vip-wrap ! 2018/10/28 下午6:30:35 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.reader-download-app ! 2018/10/28 下午6:30:39 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.help-feedback.log-xsend.reader-feedback ! 2018/10/28 下午6:32:26 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.ui-nav ! 2018/10/28 下午6:32:32 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.wk-other-new-cntent ! 2018/10/28 下午6:32:51 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.bg-opacity ! 2018/10/28 下午6:32:57 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.fix-searchbar-wrap ! 2018/10/28 下午6:33:03 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.ui-btn-btc.ui-btn-p-16 ! 2018/10/28 下午6:33:19 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.view_change_test.top-down-load-container ! 2018/10/28 下午6:33:23 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.open-in-phone ! 2018/10/28 下午6:33:27 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.addUnderLine.log-xsend.banner-text ! 2018/10/28 下午6:33:31 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html ||wkstatic.bdimg.com/static/wkview/widget/fix_searchbar/images/add-money-icon.svg$image ! 2018/10/28 下午6:33:37 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html ||wkstatic.bdimg.com/static/wkview/widget/fix_searchbar/images/bg_fix_search_5ea1707.png$image ! 2018/10/28 下午6:33:43 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.s_ipt_wr-with535.s_ipt_wr ! 2018/10/28 下午6:33:48 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.clearfix.sb-con ! 2018/10/28 下午6:33:53 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.fix-searchbar-wrap ! 2018/10/28 下午6:34:07 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.doc-tag-ticket.doc-tag ! 2018/10/28 下午6:34:12 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.fix-searchbar-wrap ! 2018/10/28 下午6:34:30 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.clearfix.reader-tools-bar-center ! 2018/10/28 下午6:35:34 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.tools-bar-small.reader-tools-bar-wrap ! 2018/10/28 下午6:35:57 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.crubms-wrap ! 2018/10/28 下午6:36:11 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.doc-bottom-text ! 2018/10/28 下午6:36:18 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.fix-searchbar-wrap ! 2018/10/28 下午6:36:34 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.doc-banner-rights-wrap ! 2018/10/28 下午6:36:38 https://wenku.baidu.com/view/379e8baaa58da0116d174924.html wenku.baidu.com##.doc-banner-text ! 2018/10/28 下午6:37:22 https://www.cnblogs.com/cjyyb/p/9495131.html www.cnblogs.com###green_channel ! 2018/10/28 下午6:38:05 https://www.cnblogs.com/cjyyb/p/9495131.html www.cnblogs.com###under_post_news > .c_ad_block.itnews ! 2018/10/28 下午6:38:10 https://www.cnblogs.com/cjyyb/p/9495131.html www.cnblogs.com###kb_block ! 2018/10/28 下午6:38:16 https://www.cnblogs.com/cjyyb/p/9495131.html www.cnblogs.com###HistoryToday ! 2018/11/2 下午6:32:46 https://blog.csdn.net/qq_31759205/article/details/75008659 blog.csdn.net##.recommend-end-box ! 2018/11/10 下午6:21:30 https://fanyi.qq.com/ ||fanyi.qq.com/images/footer-bg.ba7ba223.png$image ! 2018/11/10 下午6:21:36 https://fanyi.qq.com/ fanyi.qq.com##.foot-container ! 2018/11/23 下午10:42:31 https://blog.csdn.net/qq_34531807/article/details/80627568 blog.csdn.net###asideColumn > .text-center ! 2018/11/27 下午10:14:44 https://baike.baidu.com/item/%E9%98%BF%E6%88%BF%E5%AE%AB%E8%B5%8B/2196073?fr=aladdin ||gss1.bdstatic.com/-vo3dSag_xI4khGkpoWK1HF6hhy/baike/whfpf%3D268%2C152%2C50/sign=1061dd6d03f41bd5da06bbb437e7b3fd/d4628535e5dde711fd9079b0aaefce1b9d166131.jpg$image ! 2018/12/23 下午6:09:36 https://wenku.baidu.com/view/75906f160b4e767f5acfcedb wenku.baidu.com##.doc-tag-vip-free.doc-tag > span ! 2018/12/23 下午6:09:42 https://wenku.baidu.com/view/75906f160b4e767f5acfcedb wenku.baidu.com##.doc-tag-vip-free.doc-tag ! 2018/12/23 下午6:10:18 https://wenku.baidu.com/view/75906f160b4e767f5acfcedb ||wkstatic.bdimg.com/static/wkcommon/widget/user_bar/images/spr_bg_tip_c0ad547.png$image ! 2018/12/23 下午6:10:23 https://wenku.baidu.com/view/75906f160b4e767f5acfcedb ||wkstatic.bdimg.com/static/wkcommon/widget/user_bar/images/spr_bg_tip_c0ad547.png$image ! 2018/12/23 下午6:10:27 https://wenku.baidu.com/view/75906f160b4e767f5acfcedb ||wkstatic.bdimg.com/static/wkcommon/widget/user_bar/images/spr_bg_tip_c0ad547.png$image ! 2019/1/24 上午9:34:04 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideNewArticle > .aside-content ! 2019/1/24 上午9:34:10 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net##.clearfix.aside-content ! 2019/1/24 上午9:34:15 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideCustom67105890 > .aside-title ! 2019/1/24 上午9:34:18 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideNewArticle > .aside-title ! 2019/1/24 上午9:34:24 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideCategory > .aside-content ! 2019/1/24 上午9:34:29 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideCategory > .aside-title ! 2019/1/24 上午9:34:32 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideArchive > .aside-title ! 2019/1/24 上午9:34:38 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideArchive > .aside-content ! 2019/1/24 上午9:34:43 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideHotArticle > .aside-content ! 2019/1/24 上午9:34:47 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideHotArticle > .aside-title ! 2019/1/24 上午9:34:52 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideNewComments > .aside-title ! 2019/1/24 上午9:34:56 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net###asideNewComments > .aside-content ! 2019/1/24 上午9:35:14 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net##.item-tiling.d-flex.data-info ! 2019/1/24 上午9:35:18 https://blog.csdn.net/qq_39972971/article/details/80609097 blog.csdn.net##.clearfix.grade-box ! 2019/1/24 下午1:40:46 https://blog.csdn.net/ez_yww/article/details/79320152 blog.csdn.net###asideCustom59895271 > .aside-title ! 2019/1/24 下午1:53:20 https://blog.csdn.net/ez_yww/article/details/79320152 blog.csdn.net###csdn-toolbar