常用模板
板子贴(很多都是以前打的,码风不太一样,以后有时间重新打一遍吧。)
总板子:
#pragma GCC optimize("-O2") #include<bits/stdc++.h> #define getchar nc #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define sight(c) ('0'<=c&&c<='9') #define swap(a,b) a^=b,b^=a,a^=b #define LL long long #define deg printf #define dput put #define dputc putchar #define db double #define eho(x) for(int i=head[x];i;i=net[i]) inline char nc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } using namespace std; signed main() { return 0; }
网络流Dinic:(已封装)
#define eho(x) for(int& i=hed[x];~i;i=net[i]) #define Eho(x) for(int i=head[x];~i;i=net[i]) struct G { int head[N],net[M],fall[M],cost[M],s,t,tot,d[N],hed[N],cost2[M]; bool in[N]; queue<int> Q; G() {} inline void updata() { memcpy(cost,cost2,sizeof cost); } inline void cpy() { memcpy(cost2,cost,sizeof cost); } inline void clear() { memset(head,-1,sizeof head); tot=-1;} inline void add(int x,int y,int c) { fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=c;} inline void adds(int x,int y,int c) { add(x,y,c); add(y,x,0);} inline bool spfa() { memset(d,127,sizeof d); int x; d[s]=1; Q.push(s); in[s]=1; while (!Q.empty()) { x=Q.front(); Q.pop(); Eho(x) if (cost[i]&&d[fall[i]]>d[x]+1) { d[fall[i]]=d[x]+1; if (!in[fall[i]]) { in[fall[i]]=1,Q.push(fall[i]);} } in[x]=0; } return d[t]<INF; } inline int dfs(int x,int F) { if (x==t|| !F) return F; int flow=0,r; eho(x) if (d[x]+1==d[fall[i]]&&((r=dfs(fall[i],min(F,cost[i])))>0)) { cost[i]-=r; cost[i^1]+=r; F-=r; flow+=r; if (!F) break; } return flow; } int dinic(int A,int B) { s=A; t=B; int flow=0; while (spfa()) { memcpy(hed,head,sizeof head); flow+=dfs(s,INF); } return flow; } } G;
网络流ISAP:(已封装)
struct Maxflow{ #define N 10007 #define M 1000007 //注意这里 #define eho(x) for(int i=head[x];i;i=net[i]) #define Eho(x) for(int& i=hea[x];i;i=net[i]) #define inf (1<<27) int n,tot,fall[M],head[N],hea[N],s,t,cost[M],que[N],be,ed,net[M],gap[N],d[N],x,ret; Maxflow() {tot=1; memset(head,0,sizeof head);} inline void clear(int x,int y){tot=1; memset(head,0,sizeof head);} inline void add(int x,int y,int z){ fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=z; } inline void adds(int x,int y,int z){ add(x,y,z); add(y,x,0); } void init() { memset(gap,0,sizeof gap); memset(d,0,sizeof d); ++gap[d[t]=1]; memcpy(hea,head,sizeof hea); que[be=ed=1]=t; while (be<=ed) { x=que[be++]; eho(x) if (!d[fall[i]]) ++gap[d[fall[i]]=d[x]+1],que[++ed]=fall[i]; } } int get(int x,int fl){ if (x==t) return fl; if (!fl) return 0; int flow=0,tmp; Eho(x) if (d[x]==d[fall[i]]+1&&(tmp=get(fall[i],min(fl,cost[i])))) { flow+=tmp; fl-=tmp; cost[i]-=tmp; cost[i^1]+=tmp; if (!fl) return flow; } if (!(--gap[d[x]])) d[s]=n+1; ++gap[++d[x]],hea[x]=head[x]; return flow; } int isap(int S,int T,int Siz){ s=S; t=T; n=Siz; init(); ret=get(s,inf); while (d[s]<=n) ret+=get(s,inf); return ret; } }G;
线性规划防守战线[ZJOI 2013 day1]
#include<bits/stdc++.h> #define eps 1e-7 #define inf 1e10 using namespace std; int b; char c; inline void read(int &x) { c=getchar(); b=1; for (; !(c>='0' && c<='9'); c=getchar()) if (c=='-') b=-1; for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=getchar()); x*=b; } inline void read(long long &x) { c=getchar(); b=1; for (; !(c>='0' && c<='9'); c=getchar()) if (c=='-') b=-1; for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=getchar()); x*=b; } int n,m; double ak[1010][10100],bp[1010],cpp[10100],v; void fhb(int l,int e) { int i,j; bp[l]/=ak[l][e]; for(i=1;i<=n;i++) if(i!=e) ak[l][i]/=ak[l][e]; ak[l][e]=1/ak[l][e]; for(i=1;i<=m;i++) if(i!=l&&fabs(ak[i][e])>eps) { bp[i]-=ak[i][e]*bp[l]; for(j=1;j<=n;j++) if(j!=e) ak[i][j]-=ak[i][e]*ak[l][j]; ak[i][e]=-ak[i][e]*ak[l][e]; } v+=cpp[e]*bp[l]; for(i=1;i<=n;i++) if(i!=e) cpp[i]-=cpp[e]*ak[l][i]; cpp[e]=-cpp[e]*ak[l][e]; } double hhh() { int i,l,e; while(1) { for(i=1;i<=n;i++) if(cpp[i]>eps) break; if((e=i)==n+1) return v; double temp=inf; for(i=1;i<=m;i++) if( ak[i][e]>eps && bp[i]/ak[i][e]<temp ) temp=bp[i]/ak[i][e],l=i; if(temp==inf) return inf; fhb(l,e); } } int main() { int i,j,x,y,z; read(m); read(n); for(i=1;i<=m;i++) scanf("%lf",&bp[i]); for(i=1;i<=n;i++) { read(x); read(y); read(z); for(j=x;j<=y;j++) ak[j][i]=1; cpp[i]=z; } double ans=hhh(); cout<<(long long)(ans+0.5)<<endl; return 0; }
笛卡尔树
#include<bits/stdc++.h> typedef struct { int k,a,num; } Node; Node data[50000]; int father[50001]; int left_child[50001]; int right_child[50001]; int convert[50001]; int n; int cmp(const void *a, const void *b) { Node *p1,*p2; p1=(Node*)a; p2=(Node*)b; return p1->k - p2->k; } void insert(int index) { int i,j; i=data[index-1].num; while(i!=0 && data[convert[i]].a > data[index].a) { j=i; i=father[i]; } if(i==0) { father[j]=data[index].num; left_child[data[index].num] = j; } else { left_child[data[index].num]=right_child[i]; father[right_child[i]]=data[index].num; right_child[i]=data[index].num; father[data[index].num]=i; } } int main() { int i; scanf("%d", &n); for(i=0; i<n; i++) { scanf("%d %d", &data[i].k, &data[i].a); data[i].num=i+1; } qsort(data, n, sizeof(Node), cmp); convert[data[0].num]=0; for(i=1; i<n; i++) convert[data[i].num]=i, insert(i); printf("YES\n"); for(i=1; i<=n; i++) printf("%d %d %d\n", father[i], left_child[i], right_child[i]); return 0; }
tarjan算法
void tarjan(int x){ int v; dfn[x]=low[x]=++tim; usd[x]=1; s.push(x); eho(x) { v=fall[i]; if (dfn[v]==0) tarjan(v),low[x]=min(low[x],low[v]); else if (usd[v]) low[x]=min(low[x],dfn[v]); } if (dfn[x]==low[x]) { ++ans; do{ v=s.top();s.pop();usd[v]=0; }while (x!=v);} }
费用流:
#include<bits/stdc++.h> #define sight(c) (c>='0'&&c<='9') #define gc getchar #define M 200007 #define ner mer #define N 5007 #define inf (INT_MAX>>7) #define eho(x) for(int i=head[x];~i;i=net[i]) using namespace std; int usd[N],mer[N],val[N],head[N],net[M],fall[M],flo[M],cost[M],tot,s,t,x,n,m,y,f,c,w,maf,mic; queue<int> Q; void inline read(int &x){ static char c; for(c=gc();!sight(c);c=gc()); for(x=0;sight(c);x=x*10+c-48,c=gc()); } void inline add(int x,int y,int f,int c){ fall[++tot]=y;net[tot]=head[x];head[x]=tot;flo[tot]=f; cost[tot]=c; } bool spfa() { memset(usd,0,sizeof usd); memset(val,36,sizeof val); memset(mer,-1,sizeof mer); usd[s]=1; Q.push(s); val[s]=0; mer[s]=-2; while (!Q.empty()) { x=Q.front(); Q.pop(); eho(x) if (flo[i]&&val[x]+cost[i]<val[fall[i]]){ val[fall[i]]=val[x]+cost[i];mer[fall[i]]=i; if (!usd[fall[i]]) {usd[fall[i]]=1,Q.push(fall[i]);} } usd[x]=0; } return ~mer[t]; } int main () { // freopen("a.in","r",stdin); read(n); read(m); read(s); read(t); memset(head,-1,sizeof head); tot=-1; while (m--) { read(x); read(y); read(w); read(c); add(x,y,w,c); add(y,x,0,-c); } while (spfa()) { x=inf; for (int i=ner[t];i!=-2;i=ner[fall[i^1]]) x=min(x,flo[i]); for (int i=ner[t];i!=-2;i=ner[fall[i^1]]) { flo[i]-=x; flo[i^1]+=x; mic+=x*cost[i]; } maf+=x; } printf("%d %d\n",maf,mic); return 0; }
树状数组(区间修改,区间查询,已封装):
struct Tre{ #define L(x) (x&-x) LL a[N],b[N],sum[N]; int siz; inline void TLE(int* a,int n){for (int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];siz=n+1;} inline void Change(LL* A,int x,LL dla){for (;x<siz;x+=L(x)) A[x]+=dla;} inline LL Ask(LL *A,int x){static LL anw;for(anw=0;x;x-=L(x))anw+=A[x];return anw;} inline void change(int l,int r,LL dla) { Change(a,l,dla); Change(a,r+1,-dla); Change(b,l,dla*l); Change(b,r+1,-dla*(r+1)); } inline LL ask(int l,int r) { return (sum[r]+Ask(a,r)*(r+1)-Ask(b,r)) -(sum[l-1]+Ask(a,l-1)*l-Ask(b,l-1)); } #undef L }tree;
普通treap:
#include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') #define RR NULL #define inf 1<<29 #define random rrsbRRsb using namespace std; inline int random(){ static int seed=707; return seed=int(seed*48271LL%2147483647); } struct Treap{ int key,rap,siz; Treap *ro[2]; Treap(int k){ siz=1; key=k; rap=random(); ro[1]=ro[0]=RR; } inline void rub() { siz=1; if (ro[0]!=RR) siz+=ro[0]->siz; if (ro[1]!=RR) siz+=ro[1]->siz; } inline int cop(int x){ if (x==key) return -1; return x<key?0:1; } }; inline void read(int &x) { static char c; static int b; for (b=1,c=getchar();!sight(c);c=getchar()) if (c=='-') b=-1; for (x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } void play(Treap* &rr,int d){ Treap *k=rr->ro[d^1]; rr->ro[d^1]=k->ro[d]; k->ro[d]=rr; rr->rub(); k->rub(); rr=k; } void Insert(Treap* &rr,int x){ if (rr==RR) rr=new Treap(x); else { int d=x < rr->key?0:1; Insert(rr->ro[d],x); if (rr->ro[d]->rap > rr->rap) play(rr,d^1); } rr->rub(); } bool Find(Treap *p,int x){ while(p!=RR) { int d=p->cop(x); if (d==-1) return true; p=p->ro[d]; } return false; } void Delete(Treap* &t,int x){ int d=t->cop(x); if (d==-1) { Treap *tmp=t; if (t->ro[0]==RR) { t=t->ro[1]; delete tmp; tmp=RR; } else if (t->ro[1]==RR) { t=t->ro[0]; delete tmp; tmp=RR; } else { int k=t->ro[0]->rap<t->ro[1]->rap?0:1; play(t,k); Delete(t->ro[k],x); } } else Delete(t->ro[d],x); if (t!=RR) t->rub(); } int Kth(Treap *t,int k){ int cm=0; if (t->ro[0]) cm=t->ro[0]->siz; cm++; if (cm==k) return t->key; if (cm>k) return Kth(t->ro[0],k); return Kth(t->ro[1],k-cm); } int Rank(Treap *t,int k){ int r; if (!t) return inf; if (t->ro[0]==RR) r=0;else r=t->ro[0]->siz; if(k==t->key) return min(r+1,Rank(t->ro[0],k)); if(k<t->key) return Rank(t->ro[0],k); return r+1+Rank(t->ro[1],k); } int Pre(Treap *t,int k){ if (!t) return -inf; if (k>t->key) return max(t->key,Pre(t->ro[1],k)); return Pre(t->ro[0],k); } int Sub(Treap *t,int k){ if (!t) return inf; if (k<t->key) return min(t->key,Sub(t->ro[0],k)); return Sub(t->ro[1],k); } int n,op,x; int main () { // freopen("a.in","r",stdin); read(n); Treap* root=RR; while (n--) { read(op); read(x); switch(op){ case 1:Insert(root,x);break; case 2:Delete(root,x);break; // case 2:printf("%d\n",Find(root,x));break; case 3:printf("%d\n",Rank(root,x));break; case 4:printf("%d\n",Kth(root,x));break; case 5:printf("%d\n",Pre(root,x));break; case 6:printf("%d\n",Sub(root,x));break; } // cout<<op<<endl; } return 0; }
fhq treap:
#include<bits/stdc++.h> #define rr NULL #define inf (1<<29) #define ro son #define RR NULL using namespace std; #define random org inline int random(){ static int seed=707; return seed=int(seed*48271LL%2147483647); } struct Treap{ int key,siz,val; Treap *son[2]; Treap() {} Treap (int x){ siz=1; key=x; val=random(); son[0]=son[1]=rr; } void rub() { siz=1; if (son[0]) siz+=son[0]->siz; if (son[1]) siz+=son[1]->siz; } }; void split (Treap *now,int k,Treap* &x,Treap* &y){ if (!now) { x=y=rr; return ;} if (now->key<=k) x=now,split(x->son[1],k,x->son[1],y); if (now->key> k) y=now,split(y->son[0],k,x,y->son[0]); now->rub(); } Treap* kth(Treap* now,int k){ if (k>now->siz||!k) return rr; int com=now->son[0]?now->son[0]->siz:0; if (k<=com) return kth(now->son[0],k); if (k==com+1) return now; return kth(now->son[1],k-com-1); } Treap* merge(Treap *x,Treap *y){ if (!x) return y; if (!y) return x; if (x->val<y->val) {x->son[1]=merge(x->son[1],y);x->rub();return x;} else {y->son[0]=merge(x,y->son[0]);y->rub();return y;} } int Rank(Treap *t,int k){ int r; if (!t) return inf; if (t->son[0]==rr) r=0;else r=t->ro[0]->siz; if(k==t->key) return min(r+1,Rank(t->ro[0],k)); if(k<t->key) return Rank(t->ro[0],k); return r+1+Rank(t->ro[1],k); } int Pre(Treap *t,int k){ if (!t) return -inf; if (k>t->key) return max(t->key,Pre(t->ro[1],k)); return Pre(t->ro[0],k); } int Sub(Treap *t,int k){ if (!t) return inf; if (k<t->key) return min(t->key,Sub(t->ro[0],k)); return Sub(t->ro[1],k); } int Kth(Treap *t,int k){ int cm=0; if (t->ro[0]) cm=t->ro[0]->siz; cm++; if (cm==k) return t->key; if (cm>k) return Kth(t->ro[0],k); return Kth(t->ro[1],k-cm); } Treap* root,*x,*y,*z; int T,op,a; #define sight(c) ('0'<=c&&c<='9') inline void read(int &x) { static char c; static int b; for (b=1,c=getchar();!sight(c);c=getchar()) if (c=='-') b=-1; for (x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } int main () { read(T); while (T--) { read(op); read(a); switch (op){ case 1: split(root,a,x,y); root=merge(merge(x,new Treap(a)),y); break; case 2: split(root,a,x,z); split(x,a-1,x,y); if (y) y=merge(y->son[0],y->son[1]); root=merge(merge(x,y),z); break; case 3:printf("%d\n",Rank(root,a));break; case 4:printf("%d\n",kth(root,a)->key);break; case 5:printf("%d\n",Pre(root,a));break; case 6:printf("%d\n",Sub(root,a));break; } } }
树链剖分:
#include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') #define LL int #define gc nc #define L(x) (x&-x) #define eho(x) for(int i=head[x];i;i=net[i]) #define N 200007 LL q1[N],q2[N],gg,sum[N],a[N],T,G; int tot,fall[N<<1],net[N<<1],head[N],top[N],son[N],f[N],dp[N],siz[N],mo,be[N],ed[N],ok ,n,m,A,B,t[N],op,x,y,z,dla,OS; inline char nc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline void swap(int &x,int &y) {x^=y; y^=x; x^=y;} inline void read(LL &x){ static char c; for(c=gc();!sight(c);c=gc()); for(x=0;sight(c);c=gc()) x=x*10+c-48; } void write(LL x){if (x<10) {putchar('0'+x);return;}write(x/10); putchar('0'+x%10);} inline void ADd(int x,int y) { fall[++tot]=y; net[tot]=head[x]; head[x]=tot; } inline void add(LL &x,LL y) { x=x+y; if (x>=mo) x=x%mo; if (x<0) x=x%mo+mo; } inline void Add(LL *A,int x,int dla) {for (;x<N;x+=L(x)) add(A[x],dla);} inline void adds(int l,int r,int x) { Add(q1,l,x); Add(q1,r+1,-x); Add(q2,l,l*x%mo); Add(q2,r+1,-(r+1)*x%mo); } inline LL Query(LL *A,int x){for(G=0;x;x-=L(x)) add(G,A[x]);return G;} inline LL qurey(int l){ return (sum[l]+(l+1)*1ll*Query(q1,l)-Query(q2,l))%mo; } void dfs(int x,int fa){ siz[x]=1; son[x]=-1; dp[x]=dp[fa]+1; f[x]=fa; eho(x) if (fall[i]^fa) { dfs(fall[i],x); siz[x]+=siz[fall[i]]; if ((!(~son[x]))||siz[fall[i]]>siz[son[x]]) son[x]=fall[i]; } } void dfs2(int x,int las){ t[++ok]=x;top[x]=las; be[x]=ok; if (~son[x]) dfs2(son[x],las); eho(x) if ((fall[i]^f[x])&&(fall[i]^son[x])) dfs2(fall[i],fall[i]); ed[x]=ok; } void apd(int x,int y,LL dla){ while (top[x]!=top[y]) { if (dp[top[x]]<dp[top[y]]) swap(x,y); adds(be[top[x]],be[x],dla); x=f[top[x]]; } if (dp[x]>dp[y]) swap(x,y); adds(be[x],be[y],dla); } LL query_path(int x,int y) { LL O=0; while (top[x]!=top[y]) { if (dp[top[x]]<dp[top[y]]) swap(x,y); add(O,qurey(be[x])-qurey(be[top[x]]-1)); x=f[top[x]]; } if (dp[x]>dp[y]) swap(x,y); add(O,qurey(be[y])-qurey(be[x]-1)); return O; } int main () { read(n); read(m); read(OS);read(mo); for (int i=1;i<=n;i++) read(a[i]); for (int i=1;i< n;i++) {read(A); read(B); ADd(A,B); ADd(B,A); } dfs(OS,0); dfs2(OS,OS); for (int i=1;i<=n;i++) sum[i]=sum[i-1],add(sum[i],a[t[i]]); while (m--) { read(op); switch (op) { case 1: read(x),read(y),read(dla); apd(x,y,dla); break; case 2: read(x),read(y); write(query_path(x,y));putchar('\n'); break; case 3: read(x); read(z); adds(be[x],ed[x],z); break; case 4: read(x); T=qurey(ed[x])-qurey(be[x]-1); add(T,0ll); write(T); putchar('\n');break; } } return 0; }
主席树:
#include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') #define inf (INT_MAX>>1) #define MID ((l+r)>>1) #define N 6500007 #define SIZ 270007 using namespace std; struct Node{ int l,r,sun; }tree[N]; int tot,I,n,m,t,l,r,k,root[SIZ]; inline void read(int &x){ static char c;static int b; for(b=1,c=getchar();!sight(c);c=getchar())if (c=='-')b=-1; for(x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } void write(int x){ if (x<10) {putchar('0'+x);return;} write(x/10);putchar('0'+x%10); } void add(int old,int &id,int x,int l,int r){ id=++tot; tree[id]=tree[old]; tree[id].sun++; if (l==r) { return; } if (x<=MID) add(tree[old].l,tree[id].l,x,l,MID); else add(tree[old].r,tree[id].r,x,MID+1,r); } int query(int L,int R,int k,int l,int r){ if (l==r) return l; int cnt=tree[tree[R].l].sun-tree[tree[L].l].sun; if (cnt>=k) return query(tree[L].l,tree[R].l,k,l,MID); return query(tree[L].r,tree[R].r,k-cnt,MID+1,r); } int main () { // freopen("a.in","r",stdin); read(n); read(m); for (int i=1;i<=n;i++) { root[i]=tot+1;read(t); add(root[i-1],I,t,-inf,inf); } while(m--) { read(l); read(r); read(k); write(query(root[l-1],root[r],k,-inf,inf));putchar('\n'); } return 0; }
带修改主席树:原题
#pragma GCC optimize("-O2") #include <bits/stdc++.h> using namespace std; #define N 100005 #define int long long #define LL long long #define INF 2187654321LL #define INFF 4387654321LL #define abs(x) (x>0?x:-x) int n,q,zz,at,k,a[N],ans,AAA; LL last,L,R,Mid; #define getchar nc #define sight(c) ('0'<=c&&c<='9') inline char nc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ static char c;static int b; for (b=1,c=getchar();!sight(c);c=getchar())if (c=='-') b=-1; for (x=0;sight(c);c=getchar())x=x*10+c-48; x*=b; } struct Seg{ int l,r;int w; } T[N<<6|1]; int cnt,rt1[N],rt2[N]; #define MID (l+r>>1) void add(int k,LL l,LL r,LL pos,int &x){ x=++cnt; T[x]=T[k]; T[x].w++; if (l==r) return; if (pos<=MID) add(T[x].l,l,MID,pos,T[x].l);else add(T[x].r,MID+1,r,pos,T[x].r); } inline int query(int x,LL l,LL r,LL rr){ AAA=0; while (l^r) if (rr<=MID) r=MID,x=T[x].l; else AAA+=T[T[x].l].w,l=MID+1,x=T[x].r; return AAA+T[x].w; } #undef MID #define Mid (L+R>>1) void write(LL x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } signed main() { // freopen("b.in","r",stdin); // freopen("B.out","w",stdout); read(n);read(q);read(zz); for (int i=1;i<=n;i++) read(a[i]); for (int i=1;i<=n;i++) add(rt1[i-1],0,INFF,(LL)a[i]-zz+INF,rt1[i]); for (int i=1;i<=n;i++) add(rt2[i-1],0,INFF,(LL)a[i]+i+INF,rt2[i]); while (q--){ read(at);read(k); at=(1ll*at^abs(last))%n+1;k=(1ll*k^abs(last))%n+1; L=0;R=INFF; while (L<R){ ans=query(rt1[at],0,INFF,Mid); ans+=query(rt2[n],0,INFF,Mid+at)-query(rt2[at],0,INFF,Mid+at); if (ans>=k) R=Mid; else L=Mid+1; } writeln(last=(L-INF)); } return 0; }
lca:
inline int lca(int x,int y){ if (dep[x]<dep[y]) swap(x,y); for (int i=SIZ-1;~i;i--) if (dep[f[i][x]]>=dep[y]) x=f[i][x]; if (x==y) return x; for (int i=SIZ-1;~i;i--) if (f[i][x]^f[i][y]) x=f[i][x],y=f[i][y]; return f[0][x]; }
线性基:
void Guass() { for (int i=1;i<=n;i++) for (int j=62;~j;j--) if ((A[i]>>j)&1) if (!P[j]) {P[j]=A[i]; break;} else A[i]^=P[j]; for (int j=0;j<=62;j++) if (P[j]) OT[r++]=P[j]; }
2-sat:调整卫星[NKOJ 3814]
#include<bits/stdc++.h> #define M 4010303 #define N 2071 #define LL long long #define eho(x) for(int i=head[x];i;i=net[i]) #define MARICLE __attribute__((optimize("-O2"))) using namespace std; char c;int bb; int n,m,tot,X,Y,K; int uusd[N]; int A[N],B[N]; int fall[M],net[M],head[N],low[N],dfn[N],tim,size,in[N]; int p[N]; stack <int> S; MARICLE inline LL sr(int x){ return 1ll*x*x; } MARICLE inline void read(int &x) { c=getchar(); bb=1; for (; !(c>='0' && c<='9'); c=getchar()) if (c=='-') bb=-1; for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=getchar()); x*=bb; } MARICLE inline void read(long long &x) { c=getchar(); bb=1; for (; !(c>='0' && c<='9'); c=getchar()) if (c=='-') bb=-1; for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=getchar()); x*=bb; } MARICLE inline void add(int x,int y){ fall[++tot]=y; net[tot]=head[x]; head[x]=tot; } MARICLE void tarjan(int x) { int u; low[x]=dfn[x]=++tim; uusd[x]=1; S.push(x); eho(x){ u=fall[i]; if (dfn[u]==0) {tarjan(u);low[x]=min(low[x],low[u]);} else if (uusd[u]) low[x]=min(low[x],dfn[u]); } if (low[x]==dfn[x]) { ++size; do { u=S.top(); S.pop(); in[u]=size; uusd[u]=0; }while (x!=u); } } MARICLE bool ty(LL x){ memset(head,0,sizeof head);tot=0;tim=0; memset(dfn,0,sizeof dfn);size=0; for (int i=1;i<=2*n;i++) for (int j=i+1;j<=2*n;j++) if ((i+1)/2!=(j+1)/2&&(LL)(sr(A[i]-A[j])+sr(B[i]-B[j])<x)) add(i,p[j]),add(j,p[i]); for (int i=1; i<=2*n; i++) if (!dfn[i]) tarjan(i); for (int i=1;i<=n;i++) if (in[i<<1]==in[i*2-1]) return false; return true; } MARICLE int main () { //freopen("a.in","r",stdin); read(n); for (int i=1;i<=n;i++) p[i*2-1]=i*2,p[i*2]=i*2-1; for (int i=1;i<=n;i++){ read(X);read(Y);read(K); A[i*2-1]= (X); A[i*2 ]= (X); B[i*2-1]= (Y+K); B[i*2 ]= (Y-K); } LL r=1ll<<17,ans=0; while (r){ if(ty(ans+r)) ans+=r; r>>=1; } printf("%lld\n",ans); }
purfer序列 :明明的烦恼[HNOI 2008]
#include<bits/stdc++.h> using namespace std; const int size=168; const int data[size+1]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73, 79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191, 193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311, 313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439, 443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577, 587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709, 719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857 ,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997}; int n,len,i,a,sum,j,k,sumsum; int t[10001],ans[size+1]; void C(int n,int m) { int i,p,j; for (i=m+1;i<=n;i++) { p=i;j=1; while (p>1){while (p%data[j]==0) {ans[j]++;p/=data[j];}j++;} } for (i=1;i<=n-m;i++) { p=i;j=1; while (p>1){while (p%data[j]==0) {ans[j]--;p/=data[j];}j++;} } } int main() { //freopen("bzoj_1005.in","r",stdin); //freopen("bzoj_1005.out","w",stdout); scanf("%d",&n);len=n-2; if (n==1) { int sb; cin>>sb; if (sb==0 ||sb==-1) cout<<1; else cout<<0; return 0; } for (i=1;i<=n;i++) { scanf("%d",&a); if (a==0||len-(a-1)<0) {printf("0");return 0;} if (a==-1) {sum++;continue;}a--; C(len,a);len-=a; sumsum=sumsum+(a-1); } if (sumsum!=n-2 && sum==0) { cout<<0; return 0; } if (len) { j=1; while (sum>1){while (sum%data[j]==0) {ans[j]+=len;sum/=data[j];} j++;} } t[1]=1;k=1; for (i=1;i<=size;i++) while (ans[i]) { ans[i]--; for (j=1;j<=k;j++) t[j]*=data[i]; for (j=1;j<=k;j++) if (t[j]>9) {t[j+1]+=t[j]/10;t[j]%=10;} while (t[k+1]) {k++;t[k+1]+=t[k]/10;t[k]%=10;} } for (i=k;i>0;i--)printf("%d",t[i]); return 0; }
FFT:
#include<bits/stdc++.h> #define db double #define fo(i,a,b) for(int i=a;i<=b;i++) #define pi acos(-1) #define N 3378123 #define com rrsb using namespace std; struct com{ db r,i; com(){} com(db a,db b):r(a),i(b){} }; inline com operator + (const com A,const com B) { return com(A.r+B.r,A.i+B.i); } inline com operator - (const com A,const com B) { return com(A.r-B.r,A.i-B.i); } inline com operator * (const com A,const com B) { return com(A.r*B.r-A.i*B.i,A.i*B.r+A.r*B.i); } com a[N],b[N],X,Y; int c[N],R[N],n,m,L; char ch[N]; bool bo; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } inline void fft(com *a,int x){ fo(i,0,n-1) if(i < R[i]) swap(a[i],a[R[i]]); for (int i=1;i<n;i<<=1)// 注意这里的n不是输入的n { com wn(cos(pi/i),x*sin(pi/i)); for (int j=0;j<n;j+=(i<<1)){ com w(1,0); for (int k=0;k<i;k++,w=w*wn) { X=a[j+k]; Y=w*a[j+k+i]; a[j+k]=X+Y; a[i+j+k]=X-Y; } } } if (x==-1) fo(i,0,n-1) a[i].r=a[i].r/n; } int main () { //0freopen("a.in","r",stdin); n=read();m=read(); for(int i=0;i<=n;i++)a[i].r=read(); for(int i=0;i<=m;i++)b[i].r=read(); m+=n; for(n = 1;n <= m ;n <<= 1) ++L;// get size fo(i,0,n-1) R[i] = (R[i>>1]>>1)|((i&1)<<(L-1));//do ni pair fft(a,1); fft(b,1); fo(i,0,n) a[i]=a[i]*b[i]; fft(a,-1); fo(i,0,m) c[i]=(int)(a[i].r+0.5); fo(i,0,m) printf("%d ",c[i]); return 0; }
CDQ:
#include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') #define N 200007 inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){if (x<0) x*=-1,putchar('-'); write(x); putchar('\n'); } using namespace std; struct Node{ int a,b,c,id; inline bool operator <(const Node& A)const{ if (a==A.a) { if (b==A.b) return c<A.c; return b<A.b; } return a<A.a; } inline bool operator ==(const Node& A)const{ return A.a==a&&A.b==b&&A.c==c; } }p[N>>1],a[N>>1]; struct Tre{ #define L(x) x&-x int s[N]; void in(int x,int dla) {for (;x<N;x+=L(x)) s[x]+=dla;} int ask(int x) {static int L;for (L=0;x;x-=L(x)) L+=s[x]; return L;} void clear() {memset(s,0,sizeof s);} #undef L }Tree; int ans[N>>1],n,k,tot,id[N>>1]; inline bool cmp(const Node &x,const Node &y){ if (x.b==y.b) return x.id<y.id; return x.b<y.b; } #define Mid ((l+r)>>1) void cqh(int l,int r){ if (l==r) return; for (int i=l;i<=r;i++) p[i]=a[i],p[i].id=i; sort(p+l,p+r+1,cmp); for (int i=l;i<=r;i++) if (p[i].id<=Mid) Tree.in(p[i].c,1); else ans[a[p[i].id].id]+=Tree.ask(p[i].c); for (int i=l;i<=r;i++) if (p[i].id<=Mid) Tree.in(p[i].c,-1); cqh(l,Mid); cqh(Mid+1,r); } int main () { // freopen("cqh800Ton.in","r",stdin); read(n); read(k); for (int i=1;i<=n;i++) read(a[i].a),read(a[i].b),read(a[i].c),a[i].id=i; sort(a+1,a+n+1); for (int i=n-1;i;i--) { if (a[i]==a[i+1]) tot++; else tot=0; ans[a[i].id]=tot; } cqh(1,n); for (int i=1;i<=n;i++) id[ans[i]]++; for (int i=0;i<n;i++) writeln(id[i]); return 0; }
pollard_rho:[CZOI_NOIP2017_27]
#include<bits/stdc++.h> #define N 20005 #define LL long long using namespace std; #define INF 2e18 LL f[N],n,mo,T; LL divsor[100]; int dcnt=0; LL dmi=INF; #define TIMES 15 LL mul(LL x,LL y,LL MOD) { LL tmp=(x*y-(LL)((long double)x/MOD*y+1e-8)*MOD)%MOD; if (tmp<0) tmp+=MOD; return tmp; } LL ksm(LL x,LL y,LL MOD) { LL ans=1;x%=MOD; while (y) { if (y&1) ans=mul(ans,x,MOD); x=mul(x,x,MOD);y>>=1; } return ans; } LL GetRandom(LL n) { LL num = (((unsigned LL)rand() + 100000007)*rand())%n; return num+1; } LL Mod_Mul(LL a,LL b,LL mod) { LL msum=0; while(b) { if(b&1) msum = (msum+a)%mod; b>>=1; a = (a+a)%mod; } return msum; } LL Quk_Mul(LL a,LL b,LL mod) { LL qsum=1; while(b) { if(b&1) qsum=Mod_Mul(qsum,a,mod); b>>=1; a=Mod_Mul(a,a,mod); } return qsum; } bool Miller_Rabin(LL n) { if(n==2||n==3||n==5||n==7||n==11||n==13||n==17||n==41) return true; if(n==1||n%2==0||n%3==0||n%5==0||n%7==0||n%11==0||n%41==0||n%17==0) return false; if (n%13==0) return false; int div2=0; LL tn=n-1; while( !(tn%2) ) { div2++; tn/=2; } for(int tt=0;tt<TIMES;tt++) { LL x=GetRandom(n-1); //随机得到[1,n-1] if(x==1) continue; x=Quk_Mul(x,tn,n); LL pre=x; for(int j=0;j<div2;j++) { x = Mod_Mul(x, x, n); if(x==1&&pre!=1&&pre!=n-1) return false; pre=x; } if(x!=1) return false; } return true; } LL gcd(LL a,LL b) { if(b==0) return a; return gcd(b,a%b); } LL pollard_rho(LL dn,LL dc) { LL x,y,d,i=1,k=2; x = GetRandom(dn-1); y = x; while(1) { i++; x = (Mod_Mul(x, x, dn) + dc)%dn; d = gcd( y-x , dn ); if(1 < d && d < dn ) return d; if( y==x ) return dn; if( i==k ) { y=x; k <<= 1; } } } void Divide(LL dn,int dk) { if(dn==1) return ; if( Miller_Rabin(dn) == true ) { divsor[dcnt++]=dn; dmi = min(dmi,dn); return ; } LL dtmp=dn; while(dtmp>=dn) dtmp = pollard_rho(dtmp,dk--);//随机寻找dn的因子,dtmp Divide(dtmp, dk); Divide(dn/dtmp,dk); } void work(LL x,LL mo) { if (x==1) {printf("%d\n",1); return;} if (x==4) {printf("%d\n",8%mo); return;} memset(divsor,0,sizeof divsor); dcnt=0; if( Miller_Rabin(n) ) divsor[++dcnt]=n;else {dcnt++;Divide(x,251);} while (divsor[dcnt]==0) dcnt--; sort(divsor+1,divsor+dcnt+1); for (int i=1;i<=dcnt;i++) if (divsor[i]==divsor[i-1]) {printf("-1\n"); return;} f[0]=1; for (int i=1;i<(1<<dcnt);i++) { int s=0;f[i]=0; for (int j=i;j;j-=j&(-j),s++); for (int j=1;j<=dcnt;j++) if (i&(1<<(j-1))) f[i]=(f[i]+mul(f[i-(1<<(j-1))],ksm(divsor[s],divsor[j]-1,mo),mo))%mo; } printf("%lld\n",f[(1<<dcnt)-1]);return; } int main () { srand(unsigned(time(0))); scanf("%d",&T); while (T--) { scanf("%lld%lld",&n,&mo); work(n,mo); } return 0; }
A_star
#include<bits/stdc++.h> using namespace std; #define sight(c) ('0'<=c&&c<='9') #define N 2000005 #define Eho(x) for(int i=Head[x];i;i=Net[i]) #define eho(x) for(int i=head[x];i;i=net[i]) #define NN 5005 #define db double int L,tot,Tot,head[NN],Head[NN],net[N>>3],Net[N>>3],fall[N>>3],Fall[N>>3]; int u[NN],INF,n,X,len,ans,cnt[NN],M,s,t; db l,vis[NN],cost[N>>3],Cost[N>>1],E,co; char c; inline void read(int &x){ for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar()) x=x*10+c-48; } inline void read(db &x){ read(L); x=L; l=.1; if (c=='.') for (c=getchar();sight(c);c=getchar(),l*=0.1) x+=(c-48)*l; } inline void write(int x) {if (x<10) {putchar('0'+x);return;}write(x/10),putchar('0'+x%10);} inline void writeln(int x){write(x),putchar('\n');} inline void add(int x,int y,db co){ fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=co; } inline void Add(int x,int y,db co){ Fall[++Tot]=y; Net[Tot]=Head[x]; Head[x]=Tot; Cost[Tot]=co; } struct star{ int id; db now,add; inline bool operator<(const star& AAA) const{ return add>AAA.add; } star() {} star(int x,db a,db b):id(x),now(a),add(b){} }hep[N]; star A; queue<int> Q; void spfa(int s,int t){ Q.push(s); u[s]=1; for (int i=1;i<n;i++) vis[i]=1e9; while (!Q.empty()) { X=Q.front(); Q.pop(); Eho(X) if (vis[Fall[i]]>vis[X]+Cost[i]) { vis[Fall[i]]=vis[X]+Cost[i]; if (!u[Fall[i]]) u[Fall[i]]=1,Q.push(Fall[i]); } u[X]=0; } } void put(int id,db now,db add){hep[++len]=star(id,now,add),push_heap(hep+1,hep+1+len);} inline star get(){pop_heap(hep+1,hep+1+len);return hep[len--];} void Astar(){ put(1,0,vis[1]); while (len) { A=get(); if (A.add>E) return; if (A.id==n) {ans++;E-=A.add; continue;} if (++cnt[A.id]>INF) continue; eho(A.id) put(fall[i],(A.now)+cost[i],(A.now)+cost[i]+vis[fall[i]]); } } int main () { // freopen("a.in","r",stdin); read(n); read(M); read(E); while (M--) { read(s); read(t),read(co); add(s,t,co),Add(t,s,co); } spfa(n,1); INF=E/vis[1]; Astar(); writeln(ans); return 0; }
SAM:
#pragma optimize("-O2") #include<bits/stdc++.h> #define N 3000003 #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) using namespace std; struct S{ int c[26],fa,val; }T[N]; int tot=1,tmp,n,len,c[N],id[N],now,ti,x,last,siz[N]; long long ans; char ch[N]; inline int Sam(int x,int last){ int np=++tot; T[np].val=T[last].val+1; for(;last&&(!T[last].c[x]);last=T[last].fa) T[last].c[x]=np; if (!last) T[np].fa=1; else { int q=T[last].c[x]; if (T[last].val+1==T[q].val) T[np].fa=q; else { int nq=++tot; T[nq]=T[q]; T[nq].val=T[last].val+1; T[q].fa=T[np].fa=nq; for (;last&&T[last].c[x]==q;last=T[last].fa) T[last].c[x]=nq; } } siz[np]=1; return np; } int main () { // freopen("a.in","r",stdin); scanf("%s",ch); len=strlen(ch);last=1; for (int i=0;i<len;i++) last=Sam(ch[i]-'a',last); for (int i=1;i<=tot;i++) c[T[i].val]++; for (int i=1;i<=len;i++) c[i]+=c[i-1]; for (int i=1;i<=tot;i++) id[c[T[i].val]--]=i; for (int i=tot;i;i--) { int p=id[i]; siz[T[p].fa]+=siz[p]; if (siz[p]>1) ans=max(ans,1ll*siz[p]*T[p].val); } printf("%lld\n",ans); return 0; }
Manacher
#pragma GCC optimize("-O2") #include<bits/stdc++.h> #define N 22300007 using namespace std; int tot,len,mr,pos,ml,p[N]; char ch[N],s[N]; int main () { s[0]='$'; scanf("%s",ch); len=strlen(ch);tot=0; for (int i=0;i<len;i++) s[++tot]='#',s[++tot]=ch[i]; s[++tot]='#'; s[++tot]=21; mr=pos=ml=0; for (int i=1;i<tot;i++) { if (i<mr) p[i]=min(p[pos*2-i],mr-i); else p[i]=1; while (s[i+p[i]]==s[i-p[i]]) p[i]++; if (i+p[i]>mr) mr=i+p[i],pos=i; ml=max(ml,p[i]-1); } printf("%d\n",ml); }
KMP:
#pragma GCC optimize("-O2") #include<bits/stdc++.h> //#define getchar nc #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define sight(c) ('0'<=c&&c<='9') #define swap(a,b) a^=b,b^=a,a^=b #define LL long long #define deg printf #define dput put #define dputc putchar #define db double #define eho(x) for(int i=head[x];i;i=net[i]) inline char nc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } using namespace std; #define N 1000007 char s1[N+7],s2[N+7]; int j,len1,len2,kmp[N+7]; signed main() { scanf("%s",s1+1); len1=strlen(s1+1); scanf("%s",s2+1); len2=strlen(s2+1); for (int i=2;i<=len2;i++) { while (j&&s2[i]!=s2[j+1]) j=kmp[j]; if (s2[j+1]==s2[i]) j++; kmp[i]=j; } j=0; for (int i=1;i<=len1;i++) { while (j&&s1[i]!=s2[j+1]) j=kmp[j]; if (s2[j+1]==s1[i]) j++; if (j==len2) {writeln(i-j+1); j=kmp[j];} } for (int i=1;i<=len2;i++) writel(kmp[i]); return 0; }
ex_gcd:
#include<bits/stdc++.h> #define mod(x,b) ((x%b+b)%b) using namespace std; int x,y,a,b,t; int e_gcd(int a,int b,int &x,int &y){ if (b==0) { x=1; y=0; return a; } int yy=e_gcd(b,a%b,x,y); int tep=x; x=y; y=tep-(a/b)*y; return yy; } int main () { scanf("%d",&t); while (t--) { scanf("%d%d",&a,&b); if (e_gcd(a,b,x,y)==1) { x=mod(x,b);if (x==0) x=b; printf("%d\n",x); } else printf("Not Exist\n"); } }
带权并查集:
#include<bits/stdc++.h> #define N 201001 using namespace std; char c;int b; int n,m,k,l,r,czy,ans,fa,fb; int f[N],val[N],sum[N],net[N]; inline void read(int &x) { c=getchar(); b=1; for (; !(c>='0' && c<='9'); c=getchar()) if (c=='-') b=-1; for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=getchar()); x*=b; } /*int getfa(int i) { int x,top,j,next; x=i; while (f[x]!=x) x=f[x]; top=i; while (top!=x) { next=f[top]; f[top]=x; j=next; do { val[top]=(val[top]^val[j]); j=f[j]; } while (j!=f[j]); top=next; } return x; }*/ int getfa(int x) { if (f[x]==x) return x; int ret=getfa(f[x]); val[x]^=val[f[x]]; return f[x]=ret; } int main () { read(n); read(m); read(czy); for (int i=1;i<=n;i++) f[i]=i; for (int i=1;i<=m;i++) { read(l); read(r); read(k); l=l^(ans*czy);r=r^(ans*czy);k=k^(ans*czy); l=l-1; fa=getfa(l); fb=getfa(r); if (fa==fb) { if ((val[r]^val[l])!=k) ans=0; else ans=1; } else { if (fa>fb) { f[fa]=r; val[fa]=k^val[l];ans=1; } if (fa<fb) { f[fb]=l; val[fb]=k^val[r];ans=1; } } printf("%d\n",ans); } for (int i=1;i<=n;i++){ getfa(i); if (f[i]!=i) {sum[i]=sum[f[i]]^val[i];} else sum[i]=sum[i-1]; //printf("%d\n",sum[i]^sum[i-1]); } for (int i=1;i<=n;i++) printf("%d\n",sum[i]^sum[i-1]); return 0; }
ST:
#include<bits/stdc++.h> #define SIZ 10 #define LL long long #define N 1307 #define y1 YII #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define INF (1<<28) #define MARICLE __attribute__((optimize("-O4"))) #define getchar nc using namespace std; char c; int b; MARICLE inline char nc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } MARICLE inline void read(int &x) { c=getchar(); b=1; for (; !(c>='0' && c<='9'); c=getchar()) if (c=='-') b=-1; for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=getchar()); x*=b; } MARICLE void write(int x) { if (x<10) { putchar('0'+x); return;} write(x/10); putchar('0'+x%10); } MARICLE void write(LL x) { if (x<10) { putchar('0'+x); return;} write(x/10); putchar('0'+x%10); } int n,m,a[N][N],mi[N][N][SIZ],ma[N][N][SIZ],q,ANW,x1,x2,y1,y2,xs,ys,MI,SI,SY; LL sum[N][N]; char ch[100]; MARICLE int main () { read(n); read(m); for (int i=1,j; i<=n; i++) for (j=1; j<=m; j++) read(a[i][j]),sum[i][j]=a[i][j]+sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]; for (int i=n; i ; i--) for (int j=m; j; j--) ma[i][j][0]=mi[i][j][0]=a[i][j]; for (int k=1,i,j; k<SIZ; k++) for (i=n; i; i--) for (j=m; j; j--) { ma[i][j][k]=max(max(ma[i][j][k-1],ma[i+(1<<k-1)][j+(1<<k-1)][k-1]) ,max(ma[i+(1<<k-1)][j][k-1],ma[i][j+(1<<k-1)][k-1])); mi[i][j][k]=min(min(mi[i][j][k-1],mi[i+(1<<k-1)][j+(1<<k-1)][k-1]) ,min(mi[i+(1<<k-1)][j][k-1],mi[i][j+(1<<k-1)][k-1])); } read(q); while (q--) { c=getchar(); while (c<'A'||c>'Z') c=getchar(); c=getchar(); if (c=='U') { read(x1); x1++; read(y1); y1++; read(x2); x2++; read(y2); y2++; write(1ll*sum[x2][y2]+sum[x1-1][y1-1]-sum[x2][y1-1]-sum[x1-1][y2]); putchar('\n'); } else if (c=='I') { read(x1); x1++; read(y1); y1++; read(x2); x2++; read(y2); y2++; xs=x2-x1+1; ys=y2-y1+1; MI=min(xs,ys); SI=0; while ((1<<SI+1)<=MI) SI++; SY=1<<SI; int i=x1,j=y1; ANW=INF; while (1) { j=y1; while (1) { ANW=min(ANW,mi[i][j][SI]); if (j==y2-SY+1) break; j+=SY; if (j+SY-1>=y2) j=y2-SY+1; } if (i==x2-SY+1) break; i+=SY; if (i+SY-1>=x2) i=x2-SY+1; } write(ANW);putchar('\n'); } else { read(x1); x1++; read(y1); y1++; read(x2); x2++; read(y2); y2++; xs=x2-x1+1; ys=y2-y1+1; MI=min(xs,ys); SI=0; while ((1<<SI+1)<=MI) SI++; SY=1<<SI; int i=x1,j=y1; ANW=0; while (1) { j=y1; while (1) { ANW=max(ANW,ma[i][j][SI]); if (j==y2-SY+1) break; j+=SY; if (j+SY-1>=y2) j=y2-SY+1; } if (i==x2-SY+1) break; i+=SY; if (i+SY-1>=x2) i=x2-SY+1; } write(ANW);putchar('\n'); } } return 0; }
凸包:
#include<bits/stdc++.h> #define N 10007 #define inf INT_MAX using namespace std; struct P{ int x,y; P(){} P(int a,int b):x(a),y(b){} P operator + (const P &A)const{return P(x+A.x,y+A.y);} P operator - (const P &A)const{return P(x-A.x,y-A.y);} bool operator < (const P&A)const{if (x==A.x) return y<A.y;return x<A.x;} int operator * (const P &A)const{return x*A.y-y*A.x;} }a[N],x; inline void read(int &x) { char c=getchar();int b=1; for (; !(c>='0' && c<='9'); c=getchar()) if (c=='-') b=-1; for (x=0; c>='0' && c<='9'; x=x*10+c-'0',c=getchar()); x*=b; } int n,s[N],top; bool cmp(int x,int y){ if (a[x].x==a[y].x) return a[x].y<a[y].y; return a[x].x<a[y].x; } int main () { // freopen("a.in","r",stdin); read(n); for (int i=0;i<n;i++) { read(a[i].x),read(a[i].y);} sort(a,a+n); int m = 0; for(int i = 0; i < n; i++) { while(m>1&&((a[s[m-1]]-a[s[m-2]])*(a[i]-a[s[m-2]])<=0))m--; s[m++]=i; } int k = m; for(int i = n-2;~i; i--) { while(m>k&&(a[s[m-1]]-a[s[m-2]])*(a[i]-a[s[m-2]])<=0) m--; s[m++] =i; } if(n>1) m--; sort(s,s+m,cmp); printf("%d\n",m); for (int i=0;i<m;i++) printf("%d %d\n",a[s[i]].x,a[s[i]].y); return 0; }
矩乘:
#include<bits/stdc++.h> #define mo 1000000007 #define fo(i,a,b) for(int i=a;i<=b;i++) #define LL long long using namespace std; LL f[3][3],a[3][3],tmp[3][3],gn; int T; void cheng(LL (&a)[3][3],LL (&b)[3][3]) { memset(tmp,0,sizeof tmp); fo(i,1,2)fo(j,1,2)fo(k,1,2) {tmp[i][k]+=(1ll*a[i][j]*b[j][k])%mo; if (tmp[i][k]>mo) tmp[i][k]-=mo;} memcpy(a,tmp,sizeof tmp); } void cheng1(LL (&a)[3][3],LL (&b)[3][3]) { memset(tmp,0,sizeof tmp); fo(i,1,2)fo(k,1,2)fo(j,1,2) {tmp[i][k]+=(1ll*a[i][j]*b[j][k])%mo; if (tmp[i][k]>mo) tmp[i][k]-=mo;} memcpy(a,tmp,sizeof tmp); } void qsm (LL (&f)[3][3],LL (&a)[3][3],LL p){ while (p){ if (p&1) cheng1(f,a); cheng(a,a); p>>=1; } } int main () { scanf("%d",&T); while (T--) { scanf("%lld",&gn); f[1][1]=1; f[2][2]=1; f[1][2]=0; f[2][1]=0; a[1][1]=0; a[2][1]=1; a[1][2]=1; a[2][2]=1; qsm(f,a,gn*2+2); printf("%lld\n",f[2][2]-1); } return 0; }
快速幂:
MARICLE inline LL qsm(LL x,int y) { LL ans=1; while (y) { if (y&1) ans=ans*x%mo; x=x*x%mo; y>>=1; } return ans; }
数论函数:
#include<bits/stdc++.h> #define N 1000000 bool mark[N+5]; int prime[N+5]; int num; long long sum[N+5]; int euler[N+5]; inline int Min(int a,int b){return a<b?a:b;} void Euler() { int i,j; num = 0; memset(euler,0,sizeof(euler)); memset(prime,0,sizeof(prime)); memset(mark,0,sizeof(mark)); euler[1] = 1; // multiply function sum[1]=1; for(i=2;i<=N;i++) { if(!mark[i]) { prime[num++] = i; euler[i] = -1; } for(j=0;j<num;j++) { if(i*prime[j]>N){break;} mark[i*prime[j]] = 1; if(i%prime[j]==0) { euler[i*prime[j]] = 0; break; } else { euler[i*prime[j]] = -euler[i]; } } sum[i]=sum[i-1]+euler[i]; } } int main() { int i; int M1,M2; Euler(); int t; scanf("%d",&t); while (t--){ scanf("%d%d",&M1,&M2); long long ans = 0; int min = Min(M1,M2); /*for(i=1;i<=min;i++) { sum += euler[i]*(M1/i)*(M2/i); }*/ for (int i=1,last;i<=min;i=last+1){ last=Min(M1/(M1/i),M2/(M2/i)); ans+=(sum[last]-sum[i-1])*(M1/i)*(M2/i); } printf("%lld\n",ans); } }
点分治:
#include<bits/stdc++.h> #define N 1000000 bool mark[N+5]; int prime[N+5]; int num; long long sum[N+5]; int euler[N+5]; inline int Min(int a,int b){return a<b?a:b;} void Euler() { int i,j; num = 0; memset(euler,0,sizeof(euler)); memset(prime,0,sizeof(prime)); memset(mark,0,sizeof(mark)); euler[1] = 1; // multiply function sum[1]=1; for(i=2;i<=N;i++) { if(!mark[i]) { prime[num++] = i; euler[i] = -1; } for(j=0;j<num;j++) { if(i*prime[j]>N){break;} mark[i*prime[j]] = 1; if(i%prime[j]==0) { euler[i*prime[j]] = 0; break; } else { euler[i*prime[j]] = -euler[i]; } } sum[i]=sum[i-1]+euler[i]; } } int main() { int i; int M1,M2; Euler(); int t; scanf("%d",&t); while (t--){ scanf("%d%d",&M1,&M2); long long ans = 0; int min = Min(M1,M2); /*for(i=1;i<=min;i++) { sum += euler[i]*(M1/i)*(M2/i); }*/ for (int i=1,last;i<=min;i=last+1){ last=Min(M1/(M1/i),M2/(M2/i)); ans+=(sum[last]-sum[i-1])*(M1/i)*(M2/i); } printf("%lld\n",ans); } }
可持久化Treap:
#pragma optimize("-O2") #include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') #define rr NULL #define Ma 2147483647 #define N 500007 #define getchar nc inline char nc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ static char c;static int b; for (b=1,c=getchar();!sight(c);c=getchar()) if (c=='-') b=-1; for (x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } using namespace std; inline int rod() { static int x=23333; return x^=x<<13,x^=x>>17,x^=x<<5; } struct T{ T* s[2];int key,siz,val; T() {} T(int x){s[0]=s[1]=rr; key=x;siz=1;val=rod();} void rub() { siz=1; if (s[0]) siz+=s[0]->siz; if (s[1]) siz+=s[1]->siz; } }; T *ro[N],*X,*Y,*Z; void spilt(T* now,int k,T* &x,T* &y){ if (!now) {x=y=rr; return;} int cmp=now->s[0]?now->s[0]->siz+1:1; if (k<cmp) y=now,spilt(y->s[0],k,x,y->s[0]); else x=now,spilt(x->s[1],k-cmp,x->s[1],y); now->rub(); } void spilt2(T* now,int k,T* &x,T* &y){ if (!now) {x=y=rr; return;} if (k<=now->key) y=now,spilt2(y->s[0],k,x,y->s[0]); else x=now,spilt2(x->s[1],k,x->s[1],y); now->rub(); } T* merge(T* x,T* y) { if (!x) return y; if (!y) return x; if (x->val<y->val) {x->s[1]=merge(x->s[1],y);x->rub();return x;} y->s[0]=merge(x,y->s[0]);y->rub(); return y; } int pre(T* now,int x){ if (!now) return -Ma; if (now->key>=x) return pre(now->s[0],x); return max(now->key,pre(now->s[1],x)); } int net(T* now,int x){ if (!now) return Ma; if (now->key<=x) return net(now->s[1],x); return min(now->key,net(now->s[0],x)); } int m,n,v,op,x,tot; int main () { // freopen("a.in","r",stdin); // freopen("rr.out","w",stdout); read(m); while (m--) { read(v); read(op); read(x); switch (op) { case 1: spilt2(ro[v],x,X,Y); ro[++tot]=merge(merge(X,new T(x)),Y); break; case 2: spilt2(ro[v],x,X,Y); spilt(Y,1,Y,Z); if (Y&&Y->key^x) Z=merge(Y,Z); ro[++tot]=merge(X,Z); break; case 3: spilt2(ro[v],x,X,Y); writeln((X?X->siz:0)+1); ro[v]=merge(X,Y); ro[++tot]=ro[v];break; case 4: spilt(ro[v],x,X,Y); spilt(X,x-1,X,Z); writeln(Z->key); X=merge(X,Z); ro[v]=merge(X,Y);ro[++tot]=ro[v]; break; case 5: writeln(pre(ro[v],x));ro[++tot]=ro[v]; break; case 6: writeln(net(ro[v],x));ro[++tot]=ro[v]; break; } } return 0; }
斜率优化:
#include<bits/stdc++.h> #define B(x) (1ll*a*sum[x]*sum[x]+dp[x]-b*sum[x])//就是题解里的C(j),直线的截距,y=kx+b中的b #define K(x) (-2ll*a*sum[x])//直线的斜率 #define N 1070001 #define LL long long #define sight(C) (C<='9'&&C>='0') using namespace std; LL sum[N],q[N],n,m,x,head,tail,dp[N],a,b,c; LL check(int x,int y) {//判断当前直线与i组合的DP值 return dp[y]+a*(sum[x]-sum[y])*(sum[x]-sum[y])+b*(sum[x]-sum[y])+c; } char C;int B; double jiao(int x,int y){ //求直线的交点 return 1.0*(B(x)-B(y))/(K(x)-K(y)); } LL read(LL &x) { C=getchar(); B=1; for(;!sight(C);C=getchar()) if (C=='-') B=-1; for(x=0;sight(C);C=getchar()) x=x*10+C-'0'; x*=B; } int main () { read(n); read(a); read(b); read(c); for (int i=1;i<=n;i++) read(x),sum[i]=sum[i-1]+x; head=tail=0; q[tail++]=0; for (int i=1;i<=n;i++) { while (head+1<tail && check(i,q[head])<=check(i,q[head+1])) head++;//当前解被超过,将其出队 dp[i]=check(i,q[head]); while (head+1<tail && jiao(q[tail-2],i)<=jiao(q[tail-1],i)) tail--;//i与q【tail-1】相比,i的交点在前,所以将q【tail-1】删除 q[tail++]=i; } printf("%lld\n",dp[n]); return 0; }
分块:
#pragma GCC optimize("-O3") #include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') #define SIZ 254 #define OTK 407 #define Re register #define N 100607 #define fp puts #define l(x) (x*SIZ-SIZ+1) #define r(x) (x*SIZ) inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } using namespace std; struct RR{int num,root;}V[OTK][N]; int pre[N],pos[N],a[N],ma[N],n,m,be[N],op,l,r,v,p,q,ans,lz[N]; inline int fa(int x){ while (x^pre[x]) x=pre[x]=pre[pre[x]]; return x; } inline void push(int x) { for (Re int i=l(x);i<=r(x);i++) a[i]=pos[fa(i)],V[x][a[i]].root=V[x][a[i]].num=0,a[i]-=lz[x]; for (int i=l(x);i<=r(x);i++) pre[i]=0; lz[x]=0; } inline void reb(int x){ ma[x]=0; for (Re int i=l(x);i<=r(x);i++) { if (a[i]>ma[x]) ma[x]=a[i]; V[x][a[i]].root?pre[i]=V[x][a[i]].root: (pos[i]=a[i],V[x][a[i]].root=i,pre[i]=i); V[x][a[i]].num++; } } RR *A,*B; void play(int x,int a,int b){ A=&V[x][a]; B=&V[x][b]; B->root?pre[A->root]=B->root:(B->root=A->root,pos[A->root]=b); B->num+=A->num,A->num=A->root=0; } inline void det(int x,int v){ int &p=lz[x] ,&q=ma[x]; if ((v<<1)<=q-p) { for (Re int i=p+1;i<=p+v;i++) if (V[x][i].root) play(x,i,i+v); p+=v; } else { for (Re int i=q;i>p+v;i--) if (V[x][i].root) play(x,i,i-v); q=min(q,p+v); } } int main () { read(n); read(m); for (Re int i=1;i<=n;i++) read(a[i]),be[i]=(i-1)/SIZ+1; for (Re int i=1;i<=be[n];i++) reb(i); while (m--) { read(op); read(l); read(r); read(v); switch (op) { case 1: p=be[l]; q=be[r]; if (p^q) { push(p); push(q); for (Re int i=l;i<=r(p);i++) if (a[i]>v) a[i]-=v; for (Re int i=l(q);i<=r;i++) if (a[i]>v) a[i]-=v; for (Re int i=p+1;i<q;i++) det(i,v); reb(p); reb(q); } else { push(p); for (Re int i=l;i<=r;i++) if (a[i]>v) a[i]-=v; reb(p); } break; case 2: p=be[l]; q=be[r]; ans=0; if (p^q) { for (Re int i=l;i<=r(p);i++) if (pos[fa(i)]-lz[p]==v) ans++; for (Re int i=l(q);i<=r;i++) if (pos[fa(i)]-lz[q]==v) ans++; for (Re int i=p+1;i<q;i++) if (v+lz[i]<N) ans+=V[i][v+lz[i]].num; }else for (Re int i=l;i<=r;i++) if (pos[fa(i)]-lz[p]==v) ans++; writeln(ans); break; } } }
SG函数:
#include<bits/stdc++.h> #define gc getchar #define sight(c) ('0'<=c&&c<='9') using namespace std; int x,y,n,ans,T; inline void read(int &x){ static char c; for(c=gc();!sight(c);c=gc()); for(x=0;sight(c);c=gc()) x=x*10+c-48; } int sg(int x,int y){ long long tmp=2; for(int i=0;;i++,tmp*=2) if( (x-1)%tmp<tmp/2 && (y-1)%tmp < tmp/2 ) return i; } int main () { read(T); while (T--) { ans=0; read(n); n>>=1; for (int i=1;i<=n;i++) read(x),read(y),ans^=sg(x,y); printf("%s\n",ans?"YES":"NO"); } return 0; }
杜教筛:
#include<bits/stdc++.h> #define LL long long #define N 4000007 using namespace std; map<LL,int> ma; LL a,n; int LS,fis[N],pim[N>>3],tot,fi[N],u[N]; bool p[N]; LL F(LL x){ if (x<LS) return fis[x]; if (ma.count(x)) return ma[x]; LL ans=1; for (LL i=2,last;i<=x;i=last+1) { last=x/(x/i); ans=ans-(last-i+1)*F(x/i); } ma[x]=ans; return ans; } void LST(int LS){ fis[1]=1; for (int i=2;i<LS;i++) { if (!p[i]) u[i]=-1,pim[++tot]=i; for (int j=1;j<=tot&&i*pim[j]<LS;j++) { p[i*pim[j]]=1; if (i%pim[j]) u[i*pim[j]]=-u[i]; else{ u[i*pim[j]]=0; break;} } fis[i]=(fis[i-1]+u[i]); } } void init() { LS=min((int)pow(n,0.6667),N-47); LST(LS); } int main () { scanf("%lld %lld",&a,&n); init(); printf("%lld",F(n)-F(a-1)); }
离散对数:
#include<bits/stdc++.h> #define N 100007 #define LL long long int p[N]; int l[N>>2],pm[N>>4],tog,tot,mo,x; using namespace std; LL qsm(LL x,LL y) { static LL anw; for(anw=1;y;y>>=1,x=x*x%mo) if(y&1) anw=anw*x%mo; return anw; } void getp(int x){ for (int i=2;i<N;i++) { if (!p[i]) l[++tog]=i; for (int j=1;j<=tog&&i*l[j]<N;j++) { p[i*l[j]]=l[j]; if (i%l[j]==0) break; } } x=x-1; for (int i=1;i<=tog&&l[i]*l[i]<x;i++) if (x%l[i]==0) { pm[++tot]=l[i]; while (x%pm[tot]==0) x/=pm[tot]; } if (x!=1) pm[++tot]=x; } bool check(int x){ for (int i=1;i<=tot;i++) if (qsm(x,(mo-1)/pm[i])==1) return 0; return 1; } int PP(int x){ for (int i=1;i<=x;i++) if (check(i)) return i; } int main () { // freopen("a.in","r",stdin); scanf("%d",&x); getp(x); mo=x; printf("%d\n",PP(x)); }
生成树计数:
#include<bits/stdc++.h> #define gc getchar #define sight(c) ('0'<=c&&c<='9') //#define getchar nc #define double long double #define bug 1000007 #define SIZ 107 #define fabs(x) ((x)>0?(x):(-x)) #define zero(x) (fabs(x)>1e-9?0:1) using namespace std; int n; int f[SIZ][SIZ]; double b[SIZ][SIZ]; inline char nc () { static char buf[bug],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,bug,stdin),p1==p2)?EOF:*p1++; } inline void read(int &x){ static char c;static int b; for(c=gc(),b=1;!sight(c);c=gc()) c=='-'?b=-1:b; for(x=0;sight(c);x=x*10+c-48,c=gc()); x*=b; } double det() { double ret = 1;int sign=0; for (int i=0;i<n;i++) for (int j=0;j<n;j++) b[i][j]=f[i][j]; for (int i=0,j,k;i<n;i++) { if (zero(b[i][i])) { for (j=i+1;j<n;j++) if (!zero(b[j][i])) break; if (j == n) return 0; for (k=i;k<n;k++) swap(b[i][k],b[j][k]); sign++; } ret*= b[i][i]; for (k = i + 1; k < n; k++) b[i][k] /= b[i][i]; for (j = i + 1; j < n; j++) for (k = i + 1; k < n; k++) b[j][k] -= b[j][i] * b[i][k]; } if (sign & 1) ret = -ret; return ret; } int main () { // freopen("a.in","r",stdin); read(n); for (int i=0;i<n;i++) { f[i][i]=3; f[i][(i+1)%n]--; f[i][(i+n-1)%n]--; } printf("%.0Lf\n",det()); return 0; }
多阶差分:
#include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') #define LL long long inline void read(int &x) { static char c; for (;!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } inline void read(long long &x) { static char c;static int b; for (b=1;!sight(c);c=getchar())if (c=='-') b=-1; for (x=0;sight(c);c=getchar())x=x*10+c-48; x*=b; } #define N 501007 #define min(a,b) (a)<(b)?(a):(b) #define HP a LL len,ans2,ans,Ans,cm,n,dle,a[N],k,r,c1[N],c2[N],c3[N],c4[N],hp[N]; bool check(LL P) { int sss=sqrt(P); int tot=0; LL t1=0,t2=0,t3=0,t0=0; memset(c1,0,sizeof(c1)); memset(c2,0,sizeof(c2)); memset(c3,0,sizeof(c3)); memset(c4,0,sizeof(c4)); for(int i=1;i<=n;++i)hp[n-i+1]=HP[i]+1;//记得+1,因为怪物0血还没有死 for(int i=1;i<=n;++i) { t3+=c3[i]; t2+=c2[i]; t1+=c1[i]+t2; t0+=t1+c4[i]; hp[i]-=1ll*P*t3-t0; if(hp[i]<=0)continue; int gg=((hp[i]+P-1)/P); tot+=gg; if(tot>k)return false; c3[i+1]+=gg;c3[min(n+1,i+sss+1)]-=gg; c2[i+1]+=1ll*2*gg;c2[min(n+1,i+sss+1)]-=2*gg; c1[i+1]-=gg;c1[min(n+1,i+sss+1)]-=1ll*(1ll*2*sss-1)*gg; c4[min(n+1,i+sss+1)]-=1ll*sss*sss*gg; } return tot<=k; } int main () { read(n); read(k); for (int i=1;i<=n;i++) read(a[i]); r=1ll<<53; while (r) { if (!check(ans+r)) ans+=r; r>>=1; } printf("%lld\n",ans+1); return 0; }
哈希:
struct Ha{ #define HaN 1000007 #define HaM 1000007 int head[HaN],net[HaM],fall[HaM],tag[HaN],tot,tim, c[HaM],g[HaM]; ull h[HaM]; void _new() {++tim; tot=0;} int push(int x) { return (tag[x]^tim)?(tag[x]=tim,head[x]=0):head[x]; } int &get(ull _h,int _c) { static int hs; hs=(_h*233+_c)%HaN; for (int i=push(hs);i;i=net[i]) if (h[i]==_h&&c[i]==_c) return g[i]; h[++tot]=_h,c[tot]=_c; g[tot]=0; net[tot]=head[hs]; head[hs]=tot; return g[tot]; } }f[2];
NTT和多项式EXP:
//#pragma GCC optimize(3,"Ofast","inline") //#pragma GCC optimize("-Ofast","-funroll-all-loops") #include<bits/stdc++.h> //#define getchar nc #define sight(c) ('0'<=c&&c<='9') #define swap(a,b) a^=b,b^=a,a^=b #define LL long long #define debug(a) cout<<#a<<" is "<<a<<"\n" #define dput(a) puts("a") #define eho(x) for(int i=head[x];i;i=net[i]) #define fi first #define se second #define mo 998244353 inline char nc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } template <class T> inline void read(T &x){// unsigned static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } template <class T> void write(T x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} template <class T> inline void writeln(T x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } template <class T> inline void writel(T x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } using namespace std; LL qsm(LL x,LL y=mo-2){ static LL anw; for (anw=1,x=x%mo;y;y>>=1,x=x*x%mo) if (y&1) anw=anw*x%mo; return anw; } #define N 1000005 #define G 3 int rev[N];LL a[N],b[N]; void NTT(LL *a,int ln,int op){ int lim=1<<ln; for (int i=0;i<lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<ln-1); for (int i=0;i<lim;i++) if (i<rev[i]) swap(a[i],a[rev[i]]); for (int i=1;i<lim;i<<=1) { LL wn=qsm(G,(mo-1)/(i<<1)); if (op==-1) wn=qsm(wn); for (int j=0;j<lim;j+=i<<1) { LL w=1,X,Y; for (int k=j;k<i+j;k++,w=w*wn%mo) { X=a[k]; Y=w*a[k+i]%mo; a[k]=(X+Y)%mo; a[k+i]=(X-Y+mo)%mo; } } } if (op==-1) { LL sn=qsm(lim); for (int i=0;i<lim;i++) a[i]=a[i]*sn%mo; } } void mul(LL* a,LL *b,LL *c,int ln){//input array of len 1<<ln, return 1<<ln static LL A[N],B[N]; int lim=(1<<ln); for (int i=0;i<lim;i++) A[i]=a[i],B[i]=b[i]; for (int i=lim;i<2*lim;i++) A[i]=B[i]=0; NTT(A,ln+1,1); NTT(B,ln+1,1); for (int i=0;i<2*lim;i++) c[i]=A[i]*B[i]%mo; NTT(c,ln+1,-1); } void inv(LL *a,LL *b,int LG){ static LL C[N]; b[0]=qsm(a[0]); for (int k=1;k<=LG;k++) { mul(b,a,C,k); for (int i=0;i<(1<<k);i++) C[i]=C[i]?mo-C[i]:0; C[0]=(C[0]+2)%mo; mul(C,b,b,k); } } void Dif(LL *a,LL *b,int lim){ //传lim而不是LG for (int i=0;i<lim;i++) b[i]=a[i+1]*(i+1)%mo; b[lim-1]=0; } void Int(LL *a,LL *b,int lim){ //复杂度O(nlogn) for (int i=lim-1;i;i--) b[i]=a[i-1]*qsm(i)%mo; b[0]=0; } void Ln(LL *a,LL *b,int LG){ static LL C[N]; inv(a,b,LG); Dif(a,C,1<<LG); mul(b,C,b,LG); Int(b,b,1<<LG); } void exp(LL *a,LL *b,int LG){ static LL D[N]; b[0]=1; for (int k=1;k<=LG;k++) { Ln(b,D,k); for (int i=0;i<(1<<(k));i++) D[i]=(a[i]-D[i]+mo)%mo; D[0]=(D[0]+1)%mo; mul(b,D,b,k); } } int n,T,X; LL fac[N]; signed main() { #ifdef LOCAL // freopen("test.in", "r", stdin); // freopen("test.out", "w", stdout); #endif a[1]=1; exp(a,b,17); b[0]=0; exp(b,a,17); fac[0]=1; for (int i=1;i<N;i++) fac[i]=fac[i-1]*i%mo; read(T); while(T--) { read(X); writeln(a[X]*fac[X]%mo); } return 0; } /* 3 1 3 3 1 1 3 3 1 */
差不多就这些吧。