我的模板库【填坑中】
来源:互联网 发布:app无网络提示 编辑:程序博客网 时间:2024/05/22 06:58
字符串
- AC自动机
- manacher
【APIO2014】uoj103 Palindromes【2017.7.12】
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn=600010;#define LL long longchar s[maxn];int trans[maxn][30],fail[maxn],val[maxn],cnt[maxn],ord[maxn],mxl[maxn],num[maxn],fa[maxn][20],pos[maxn],n,tot=1;int main(){ //int xxx=0; //freopen("b.in","r",stdin); //freopen("b.out","w",stdout); LL ans=0; int last=1,u,nu,v,nv,x,y,lim=0,mx,id; scanf("%s",s+1); n=strlen(s+1); for (int i=1;i<=n;i++) { x=s[i]-'a'+1; u=last; val[last=nu=++tot]=i; while (u&&!trans[u][x]) { trans[u][x]=nu; u=fail[u]; } if (!u) fail[nu]=1; else { v=trans[u][x]; if (val[v]==val[u]+1) fail[nu]=v; else { val[nv=++tot]=val[u]+1; fail[nv]=fail[v]; fail[v]=fail[nu]=nv; for (int j=1;j<=26;j++) trans[nv][j]=trans[v][j]; while (u&&trans[u][x]==v) { trans[u][x]=nv; u=fail[u]; } } } } pos[0]=1; for (int i=1;i<=n;i++) num[pos[i]=trans[pos[i-1]][s[i]-'a'+1]]++; for (int i=1;i<=tot;i++) cnt[val[i]]++; for (int i=1;i<=n;i++) cnt[i]+=cnt[i-1]; for (int i=1;i<=tot;i++) ord[cnt[val[i]]--]=i; for (int i=tot;i>=1;i--) num[fail[ord[i]]]+=num[ord[i]]; while ((1<<lim)<tot) lim++; for (int i=1;i<=tot;i++) fa[i][0]=fail[i]; for (int k=1;k<=lim;k++) for (int i=1;i<=tot;i++) fa[i][k]=fa[fa[i][k-1]][k-1]; for (int i=n*2+1;i>=1;i--) s[i]=(i&1)?'$':s[i/2]; s[0]='@'; s[2*n+2]='%'; mx=0; for (int i=1;i<=2*n+1;i++) { if (i<=mx) mxl[i]=min(mxl[2*id-i],mx-i); //printf("%d:%d,%d,%d\n",i,id,mx,mxl[i]); while (s[i-mxl[i]-1]==s[i+mxl[i]+1]) { mxl[i]++; //xxx++; } if (i+mxl[i]>mx) { for (int j=mx;j<=i+mxl[i];j+=2) { x=j/2; y=(2*i-j)/2+1; u=pos[x]; for (int k=lim;k>=0;k--) if (val[fa[u][k]]>=x-y+1) u=fa[u][k]; ans=max(ans,(LL)num[u]*(x-y+1)); } mx=i+mxl[i]; id=i; } } //printf("%d\n",xxx); printf("%lld\n",ans);}
- 后缀数组
poj1743 Musical Theme【2017.4.21】
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int c=90,maxn=30010,oo=0x3f3f3f3f;int a[maxn],sa[maxn],rank[maxn],height[maxn],f[maxn],cnt[maxn],n;void solve(){ int m,p,l,r,mid,ok,mnp,mxp; memset(a,0,sizeof(a)); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<n;i++) a[i]=a[i+1]-a[i]+c; a[n]=0; m=190; for (int i=1;i<=m;i++) cnt[i]=0; for (int i=1;i<n;i++) cnt[rank[i]=a[i]]++; for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1]; for (int i=n-1;i;i--) sa[cnt[a[i]]--]=i; for (int k=1;k<n;k<<=1) { p=0; for (int i=n-k;i<n;i++) f[++p]=i; for (int i=1;i<n;i++) if (sa[i]-k>=1) f[++p]=sa[i]-k; for (int i=1;i<=m;i++) cnt[i]=0; for (int i=1;i<n;i++) cnt[rank[f[i]]]++; for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1]; for (int i=n-1;i;i--) sa[cnt[rank[f[i]]]--]=f[i]; for (int i=1;i<n;i++) f[i]=rank[i]; rank[sa[1]]=1; for (int i=2;i<n;i++) if (f[sa[i]]!=f[sa[i-1]]||f[sa[i]+k]!=f[sa[i-1]+k]) rank[sa[i]]=rank[sa[i-1]]+1; else rank[sa[i]]=rank[sa[i-1]]; m=rank[sa[n-1]]; if (m>=n-1) break; } for (int i=1;i<n;i++) { height[rank[i]]=height[rank[i-1]]; if (height[rank[i]]) height[rank[i]]--; while (a[i+height[rank[i]]]==a[sa[rank[i]-1]+height[rank[i]]]) height[rank[i]]++; } l=0; r=n-1; while (l<r) { mid=l+r+1>>1; ok=0; for (int i=1;i<n&&!ok;i++) if (height[i]>=mid) { mxp=max(mxp,sa[i]); mnp=min(mnp,sa[i]); if (mxp-mnp>mid) ok=1; } else mxp=mnp=sa[i]; if (ok) l=mid; else r=mid-1; } //printf("%d\n",l+1); if (l>=4) printf("%d\n",l+1); else printf("0\n");}int main(){ while (scanf("%d",&n)&&n) solve();}
poj2774 Long Long Message【2017.5.17】
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=400010;char s[maxn];int sa[maxn],rank[maxn],height[maxn],f[maxn],g[maxn],cnt[maxn];int main(){ int n,m=27,l,p,ans=0; scanf("%s",s+1); l=strlen(s+1); s[l+1]='z'+1; scanf("%s",s+l+2); n=strlen(s+1); for (int i=1;i<=n;i++) cnt[rank[i]=s[i]-'a'+1]++; for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1]; for (int i=n;i;i--) sa[cnt[rank[i]]--]=i; for (int k=1;;k<<=1) { p=0; for (int i=n-k+1;i<=n;i++) f[++p]=i; for (int i=1;i<=n;i++) if (sa[i]>k) f[++p]=sa[i]-k; for (int i=1;i<=m;i++) cnt[i]=0; for (int i=1;i<=n;i++) cnt[rank[f[i]]]++; for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1]; for (int i=n;i;i--) sa[cnt[rank[f[i]]]--]=f[i]; for (int i=1;i<=n;i++) g[i]=rank[i]; rank[sa[1]]=1; for (int i=2;i<=n;i++) rank[sa[i]]=rank[sa[i-1]]+(g[sa[i]]!=g[sa[i-1]]||g[sa[i]+k]!=g[sa[i-1]+k]); m=rank[sa[n]]; if (m>=n) break; } for (int i=1;i<=n;i++) { height[rank[i]]=height[rank[i-1]]; if (height[rank[i]]) height[rank[i]]--; while (s[i+height[rank[i]]]==s[sa[rank[i]-1]+height[rank[i]]]) height[rank[i]]++; } for (int i=2;i<=n;i++) if ((sa[i]<=l&&sa[i-1]>=l+2)||(sa[i]>=l+2&&sa[i-1]<=l)) ans=max(ans,height[i]); printf("%d\n",ans);}
- 后缀自动机
SPOJ NSUBSTR Substrings【2017.4.21】
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=500010;char s[maxn];int fail[maxn],val[maxn],trans[maxn][30],cnt[maxn],f[maxn],num[maxn],ans[maxn],n,tot=1;int main(){ int p,last=1,x,np,q,nq; scanf("%s",s+1); n=strlen(s+1); for (int i=1;i<=n;i++) { x=s[i]-'a'; p=last; val[last=np=++tot]=val[p]+1; while (p&&!trans[p][x]) { trans[p][x]=np; p=fail[p]; } if (!p) fail[np]=1; else { q=trans[p][x]; if (val[q]==val[p]+1) fail[np]=q; else { val[nq=++tot]=val[p]+1; fail[nq]=fail[q]; fail[q]=fail[np]=nq; for (int j=0;j<26;j++) trans[nq][j]=trans[q][j]; while (p&&trans[p][x]==q) { trans[p][x]=nq; p=fail[p]; } } } } p=1; for (int i=1;i<=n;i++) { p=trans[p][s[i]-'a']; cnt[p]++; } for (int i=1;i<=tot;i++) num[val[i]]++; for (int i=n-1;i;i--) num[i]+=num[i+1]; for (int i=1;i<=tot;i++) f[num[val[i]]--]=i; for (int i=1;i<=tot;i++) { cnt[fail[f[i]]]+=cnt[f[i]]; ans[val[f[i]]]=max(ans[val[f[i]]],cnt[f[i]]); } for (int i=n-1;i;i--) ans[i]=max(ans[i],ans[i+1]); for (int i=1;i<=n;i++) printf("%d\n",ans[i]);}
poj2774 Long Long Message【2017.5.17】
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=200010;char s1[maxn],s2[maxn];int trans[maxn][30],fail[maxn],val[maxn],n,m,tot=1;int main(){ int last=1,x,p,q,np,nq,now=0,ans=0; scanf("%s",s1+1); n=strlen(s1+1); for (int i=1;i<=n;i++) { x=s1[i]-'a'+1; p=last; val[last=np=++tot]=val[p]+1; while (p&&!trans[p][x]) { trans[p][x]=np; p=fail[p]; } if (!p) fail[np]=1; else { q=trans[p][x]; if (val[q]==val[p]+1) fail[np]=q; else { val[nq=++tot]=val[p]+1; fail[nq]=fail[q]; fail[q]=fail[np]=nq; for (int j=1;j<=26;j++) trans[nq][j]=trans[q][j]; while (p&&trans[p][x]==q) { trans[p][x]=nq; p=fail[p]; } } } } scanf("%s",s2+1); m=strlen(s2+1); p=1; for (int i=1;i<=m;i++) { x=s2[i]-'a'+1; if (trans[p][x]) { p=trans[p][x]; now++; } else { while (p&&!trans[p][x]) p=fail[p]; if (p) { now=val[p]+1; p=trans[p][x]; } else { now=0; p=1; } } ans=max(ans,now); } printf("%d\n",ans);}
- 回文自动机
【APIO2014】bzoj3676 回文串
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define LL long longconst int maxn=600010;char s[maxn];int val[maxn],fail[maxn],trans[maxn][30],cnt[maxn],num[maxn],f[maxn],n;int main(){ int tot=1,last=0,p,np,x,q; LL ans=0; scanf("%s",s+1); n=strlen(s+1); fail[0]=fail[1]=1; val[1]=-1; for (int i=1;i<=n;i++) { x=s[i]-'a'; p=last; while (s[i-val[p]-1]!=s[i]) p=fail[p]; if (!trans[p][x]) { val[np=++tot]=val[p]+2; q=fail[p]; while (s[i-val[q]-1]!=s[i]) q=fail[q]; fail[np]=trans[q][x]; trans[p][x]=np; } cnt[last=trans[p][x]]++; } for (int i=2;i<=tot;i++) num[val[i]]++; for (int i=1;i<=n;i++) num[i]+=num[i-1]; for (int i=2;i<=tot;i++) f[num[val[i]]--]=i; for (int i=tot-1;i;i--) { ans=max(ans,(LL)val[f[i]]*cnt[f[i]]); cnt[fail[f[i]]]+=cnt[f[i]]; } printf("%lld\n",ans);}
树形数据结构
- treap
bzoj3224 普通平衡树【2017.4.17】
#include<cstdio>#include<algorithm>using namespace std;const int maxn=100010,no=2e9+100;int rd(){ int x=0,f=1; char c=getchar(); while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); } while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f;}struct treap{ int son[2][maxn],v[maxn],w[maxn],siz[maxn],cnt[maxn],rt,tot; void upd(int p) { siz[p]=siz[son[0][p]]+siz[son[1][p]]+cnt[p]; } void rot(int &p,int fl) { int u=son[fl][p],v=son[fl^1][u]; son[fl][p]=v; son[fl^1][u]=p; upd(p); p=u; upd(p); } void ins(int &p,int x) { if (!p) { p=++tot; v[p]=x; w[p]=rand(); siz[p]=cnt[p]=1; return; } siz[p]++; if (v[p]==x) { cnt[p]++; return; } int flag=x>v[p]; ins(son[flag][p],x); if (w[son[flag][p]]>w[p]) rot(p,flag); } void del(int &p,int x) { if (v[p]==x) { if (son[0][p]*son[1][p]==0) { cnt[p]--; siz[p]--; if (!cnt[p]) p=son[0][p]+son[1][p]; } else { int fl=w[son[0][p]]<w[son[1][p]]; rot(p,fl); siz[p]--; del(son[fl^1][p],x); } return; } siz[p]--; del(son[x>v[p]][p],x); } int rank(int p,int x) { if (v[p]==x) return siz[son[0][p]]+1; if (x<v[p]) return rank(son[0][p],x); return siz[son[0][p]]+cnt[p]+rank(son[1][p],x); } int qry(int p,int x) { if (x<=siz[son[0][p]]) return qry(son[0][p],x); if (x<=siz[son[0][p]]+cnt[p]) return v[p]; return qry(son[1][p],x-(siz[son[0][p]]+cnt[p])); } int pre(int p,int x) { if (!p) return no; if (v[p]<x) { int y=pre(son[1][p],x); return y==no?v[p]:y; } return pre(son[0][p],x); } int suc(int p,int x) { if (!p) return no; if (v[p]>x) { int y=suc(son[0][p],x); return y==no?v[p]:y; } return suc(son[1][p],x); } void Ins(int x) { ins(rt,x); } void Del(int x) { del(rt,x); } int Rank(int x) { return rank(rt,x); } int Qry(int x) { return qry(rt,x); } int Pre(int x) { return pre(rt,x); } int Suc(int x) { return suc(rt,x); }}t;int main(){ int n,opt; n=rd(); while (n--) { opt=rd(); switch (opt) { case 1:t.Ins(rd());break; case 2:t.Del(rd());break; case 3:printf("%d\n",t.Rank(rd()));break; case 4:printf("%d\n",t.Qry(rd()));break; case 5:printf("%d\n",t.Pre(rd()));break; case 6:printf("%d\n",t.Suc(rd()));break; } }}
- splay
bzoj3224 普通平衡树【2017.4.17】
#include<cstdio>#include<algorithm>using namespace std;const int maxn=100010,no=2e9+1000;int rd(){ int x=0,f=1; char c=getchar(); while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); } while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f;}int fa[maxn],son[maxn][2],v[maxn],cnt[maxn],siz[maxn],tot,rt;void pause(){ int x=0; x=1;}void upd(int p){ siz[p]=siz[son[p][0]]+siz[son[p][1]]+cnt[p];}void rot(int p,int fl){ int u=son[p][fl],v=son[u][fl^1]; fa[u]=fa[p]; if (!fa[u]) rt=u; else son[fa[u]][son[fa[u]][1]==p]=u; son[p][fl]=v; if (v) fa[v]=p; son[u][fl^1]=p; fa[p]=u; upd(p); upd(u);}void splay(int u){ int v,x,w,y; upd(u); while (rt!=u) { v=fa[u]; x=son[v][1]==u; if (v==rt) rot(v,x); else { w=fa[v]; y=son[w][1]==v; if (x==y) rot(w,y),rot(v,x); else rot(v,x),rot(w,y); } }}void ins(int p,int x,int f,int fl){ if (!p) { p=++tot; cnt[p]=1; v[p]=x; if (f) { fa[p]=f; son[f][fl]=p; } else rt=p; splay(p); return; } if (x==v[p]) { cnt[p]++; splay(p); return; } int fl2=x>v[p]; ins(son[p][fl2],x,p,fl2);}void del(int p,int x,int f,int fl){ if (v[p]==x) { if (cnt[p]>1) { cnt[p]--; splay(p); } else { if (son[p][0]*son[p][1]==0) { if (f) { son[f][fl]=son[p][0]+son[p][1]; if (son[f][fl]) { fa[son[f][fl]]=f; splay(son[f][fl]); } else splay(f); } else fa[rt=son[p][0]+son[p][1]]=0; } else { int fl2=siz[son[p][0]]<siz[son[p][1]]; rot(p,fl2); del(p,x,fa[p],fl2^1); } } } else { int fl2=x>v[p]; del(son[p][fl2],x,p,fl2); }}int rank(int p,int x){ if (x==v[p]) { splay(p); return siz[son[p][0]]+1; } if (x<v[p]) return rank(son[p][0],x); return rank(son[p][1],x);}int qry(int p,int x){ if (x<=siz[son[p][0]]) return qry(son[p][0],x); if (x<=siz[son[p][0]]+cnt[p]) { splay(p); return v[p]; } return qry(son[p][1],x-siz[son[p][0]]-cnt[p]);}int pre(int p,int x){ if (!p) return no; if (v[p]<x) { int y=pre(son[p][1],x); if (y==no) { splay(p); return v[p]; } return y; } return pre(son[p][0],x);}int suc(int p,int x){ if (!p) return no; if (v[p]>x) { int y=suc(son[p][0],x); if (y==no) { splay(p); return v[p]; } return y; } return suc(son[p][1],x);}int main(){ /*freopen("phs.in","r",stdin); freopen("phs.out","w",stdout);*/ int n,opt; n=rd(); while (n--) { if (n==1) pause(); opt=rd(); switch (opt) { case 1:ins(rt,rd(),0,0);break; case 2:del(rt,rd(),0,0);break; case 3:printf("%d\n",rank(rt,rd()));break; case 4:printf("%d\n",qry(rt,rd()));break; case 5:printf("%d\n",pre(rt,rd()));break; case 6:printf("%d\n",suc(rt,rd()));break; } }}
【AHOI2006】bzoj1269 文本编辑器【2017.4.19】
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define rt son[1][0]const int maxn=4000010;char s[maxn],s1[maxn],chr[maxn];int fa[maxn],son[maxn][2],inv[maxn],size[maxn],tot=3;void down(int u){ if (inv[u]) { swap(son[u][0],son[u][1]); if (son[u][0]) inv[son[u][0]]^=1; if (son[u][1]) inv[son[u][1]]^=1; inv[u]=0; }}void upd(int u){ size[u]=size[son[u][0]]+size[son[u][1]]+1;}int find(int u,int p){ down(u); if (p<=size[son[u][0]]) return find(son[u][0],p); if (p==size[son[u][0]]+1) return u; return find(son[u][1],p-size[son[u][0]]-1);}void rot(int u,int f){ int v=son[u][f],w=son[v][f^1],x=fa[u],fx=son[x][1]==u; son[u][f]=w; if (w) fa[w]=u; son[v][f^1]=u; fa[u]=v; son[x][fx]=v; fa[v]=x; upd(u); upd(v);}void get(int p,int f){ int u=find(rt,p),x,y,fx,fy; while (fa[u]!=f) { x=fa[u]; fx=son[x][1]==u; y=fa[x]; fy=son[y][1]==x; if (y==f) rot(x,fx); else { if (fx==fy) rot(y,fy),rot(x,fx); else rot(x,fx),rot(y,fy); } }}int build(int l,int r){ if (l>r) return 0; int mid=l+r>>1,ret; chr[ret=++tot]=s[mid]; son[ret][0]=build(l,mid-1); if (son[ret][0]) fa[son[ret][0]]=ret; son[ret][1]=build(mid+1,r); if (son[ret][1]) fa[son[ret][1]]=ret; upd(ret); return ret;}int main(){ int m,n,p=1; scanf("%d",&m); son[1][0]=2; son[2][0]=3; fa[2]=1; fa[3]=2; size[2]=2; size[3]=1; while (m--) { scanf("%s",s1); switch (s1[0]) { case 'M':scanf("%d",&p);p++;break; case 'I': scanf("%d",&n); gets(s+1); gets(s+1); get(p,1); get(p+1,rt); son[son[rt][1]][0]=build(1,n); fa[son[son[rt][1]][0]]=son[rt][1]; upd(son[rt][1]); upd(rt); break; case 'D': scanf("%d",&n); get(p,1); get(p+n+1,rt); son[son[rt][1]][0]=0; upd(son[rt][1]); upd(rt); break; case 'R': scanf("%d",&n); get(p,1); get(p+n+1,rt); inv[son[son[rt][1]][0]]^=1; break; case 'G': get(p+1,1); printf("%c\n",chr[rt]); break; case 'P':p--;break; case 'N':p++;break; } }}
- 替罪羊树
- kdtree
bzoj2648 SJY摆棋子【2017.4.21】
#include<cstdio>#include<algorithm>using namespace std;#define R(k) for (int k=0;k<2;k++)const int maxn=2000010,oo=0x3f3f3f3f;int D,ans;struct Point{ int x[2]; void rd() { R(k) scanf("%d",&x[k]); } bool operator < (const Point &p) const { return x[D]<p.x[D]; }}a[maxn],p;int lson[maxn],rson[maxn],mx[maxn][2],mn[maxn][2],tot,rt;void upd(int p){ R(k) { mx[p][k]=mn[p][k]=a[p].x[k]; if (lson[p]) { mx[p][k]=max(mx[p][k],mx[lson[p]][k]); mn[p][k]=min(mn[p][k],mn[lson[p]][k]); } if (rson[p]) { mx[p][k]=max(mx[p][k],mx[rson[p]][k]); mn[p][k]=min(mn[p][k],mn[rson[p]][k]); } }}int build(int L,int R,int d){ if (L>R) return 0; int mid=L+R>>1; D=d; nth_element(a+L,a+mid,a+R+1); lson[mid]=build(L,mid-1,d^1); rson[mid]=build(mid+1,R,d^1); upd(mid); return mid;}void ins(int &u,int d){ if (!u) { a[u=++tot]=p; R(k) mn[u][k]=mx[u][k]=p.x[k]; return; } if (p.x[d]<a[u].x[d]) ins(lson[u],d^1); else ins(rson[u],d^1); upd(u);}int mindis(int u){ if (!u) return oo; int ret=0; R(k) { if (mn[u][k]>p.x[k]) ret+=mn[u][k]-p.x[k]; if (mx[u][k]<p.x[k]) ret+=p.x[k]-mx[u][k]; } return ret;}void qry(int u,int d){ int ret=0,lmn=mindis(lson[u]),rmn=mindis(rson[u]); R(k) ret+=abs(p.x[k]-a[u].x[k]); ans=min(ans,ret); if (lmn<rmn) { if (lmn<ans) qry(lson[u],d^1); if (rmn<ans) qry(rson[u],d^1); } else { if (rmn<ans) qry(rson[u],d^1); if (lmn<ans) qry(lson[u],d^1); }}int main(){ int n,m,opt; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) a[i].rd(); rt=build(1,n,0); tot=n; while (m--) { scanf("%d",&opt); R(k) scanf("%d",&p.x[k]); if (opt==1) ins(rt,0); else { ans=oo; qry(rt,0); printf("%d\n",ans); } }}
- 左偏树
- 主席树
poj2104 K-th Number【2017.5.16】
#include<cstdio>#include<algorithm>using namespace std;const int maxn=2000010;int rd(){ int x=0,f=1; char c=getchar(); while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); } while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f;}int a[maxn],ord[maxn],rt[maxn],sum[maxn],lson[maxn],rson[maxn],n,tot;int modi(int bro,int L,int R,int x){ int u=++tot; sum[tot]=sum[bro]+1; if (L==R) return u; int mid=(L+R)/2; if (x<=mid) { lson[u]=modi(lson[bro],L,mid,x); rson[u]=rson[bro]; } else { lson[u]=lson[bro]; rson[u]=modi(rson[bro],mid+1,R,x); } return u;}int qry(int u,int v,int L,int R,int k){ if (L==R) return L; int mid=(L+R)/2; if (k<=sum[lson[u]]-sum[lson[v]]) return qry(lson[u],lson[v],L,mid,k); return qry(rson[u],rson[v],mid+1,R,k-(sum[lson[u]]-sum[lson[v]]));}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int m,q,l,r,k; n=rd(); q=rd(); for (int i=1;i<=n;i++) ord[i]=a[i]=rd(); sort(ord+1,ord+n+1); m=unique(ord+1,ord+n+1)-ord-1; for (int i=1;i<=n;i++) a[i]=lower_bound(ord+1,ord+m+1,a[i])-ord; for (int i=1;i<=n;i++) rt[i]=modi(rt[i-1],1,m,a[i]); while (q--) { l=rd(); r=rd(); k=rd(); printf("%d\n",ord[qry(rt[r],rt[l-1],1,m,k)]); }}
数论
- 中国剩余定理
- 离散对数
bzoj4128 Matrix【2017.5.18】
#include<cstdio>#include<cmath>#include<map>#include<algorithm>using namespace std;#define LL unsigned long longconst int maxn=75,r=131;int n,p,m;map<LL,int> mp;int inc(int x,int y){ x+=y;return x>=p?x-p:x;}int dec(int x,int y){ x-=y;return x<0?x+p:x;}int inverse(int x){ int ret=1; for (int k=p-2;k;k>>=1,x=x*x%p) if (k&1) ret=ret*x%p; return ret;}struct mat{ int a[maxn][maxn]; LL h; void get() { h=0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) h=h*r+a[i][j]; } void rd() { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) scanf("%d",&a[i][j]); get(); } void init() { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=(i==j); get(); } mat operator * (const mat &m) const { mat ret; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { ret.a[i][j]=0; for (int k=1;k<=n;k++) ret.a[i][j]=inc(ret.a[i][j],a[i][k]*m.a[k][j]%p); } ret.get(); return ret; } mat inv() { mat ret; int x,t; ret.init(); for (int i=1;i<=n;i++) { x=0; for (int j=i;j<=n;j++) if (a[j][i]) { x=j; break; } if (x!=i) for (int j=1;j<=n;j++) { swap(a[i][j],a[x][j]); swap(ret.a[i][j],ret.a[x][j]); } t=inverse(a[i][i]); for (int j=1;j<=n;j++) { a[i][j]=a[i][j]*t%p; ret.a[i][j]=ret.a[i][j]*t%p; } for (int j=1;j<=n;j++) if (j!=i) { t=a[j][i]; for (int k=1;k<=n;k++) { a[j][k]=dec(a[j][k],a[i][k]*t%p); ret.a[j][k]=dec(ret.a[j][k],ret.a[i][k]*t%p); } } } ret.get(); return ret; }}a,b,c;int main(){ scanf("%d%d",&n,&p); a.rd(); b.rd(); m=sqrt(p); c.init(); for (int i=0;i<m;i++) { if (!mp.count(c.h)) mp[c.h]=i; c=c*a; if (b.h==c.h) { printf("%d\n",i+1); return 0; } } c=c.inv(); for (int i=1;;i++) { b=b*c; if (mp.count(b.h)) { printf("%d\n",i*m+mp[b.h]); return 0; } }}
- 杜教筛
bzoj3944 Sum【2017.7.14】
#include<cstdio>#include<algorithm>using namespace std;#define LL long longconst int maxn=2000000,p=2333333;int prm[maxn+5],fir[p+5],ne[p+5],val[p+5],tot,num;LL phi[maxn+5],mu[maxn+5],ansphi[p+5],ansmu[p+5];int find(int n,LL &resphi,LL &resmu){ for (int i=fir[n%p];i;i=ne[i]) if (val[i]==n) { resphi=ansphi[i]; resmu=ansmu[i]; return 1; } return 0;}void ins(int n,LL resphi,LL resmu){ if (tot>p) return; int x=n%p; tot++; ne[tot]=fir[x]; fir[x]=tot; val[tot]=n; ansphi[tot]=resphi; ansmu[tot]=resmu;}void solve(int n,LL &resphi,LL &resmu){ if (n<=maxn) { resphi=phi[n]; resmu=mu[n]; return; } if (find(n,resphi,resmu)) return; LL tphi,tmu; resphi=n*(n+1LL)/2; resmu=1; for (unsigned int i=2,j;i<=n;i=j+1) { j=n/(n/i); solve(n/i,tphi,tmu); resphi-=(j-i+1)*tphi; resmu-=(j-i+1)*tmu; } ins(n,resphi,resmu);}int main(){ //freopen("a.in","r",stdin); int n; LL resphi,resmu; mu[1]=phi[1]=1; for (int i=2;i<=maxn;i++) { if (!phi[i]) { prm[++num]=i; phi[i]=i-1; mu[i]=-1; } for (int j=1;j<=num&&(LL)i*prm[j]<=maxn;j++) if (i%prm[j]) { mu[i*prm[j]]=-mu[i]; phi[i*prm[j]]=phi[i]*(prm[j]-1); } else { mu[i*prm[j]]=0; phi[i*prm[j]]=phi[i]*prm[j]; break; } phi[i]+=phi[i-1]; mu[i]+=mu[i-1]; } int T; scanf("%d",&T); while (T--) { scanf("%d",&n); solve(n,resphi,resmu); printf("%lld %lld\n",resphi,resmu); }}
bzoj4916神犇和蒟蒻【2017.7.15】
#include<cstdio>#include<algorithm>using namespace std;#define LL long longconst int p=1000000007,maxn=1000000,mod=2333333;int inc(int x,int y){ x+=y; return x>=p?x-p:x;}int dec(int x,int y){ x-=y; return x<0?x+p:x;}int prm[maxn+10],phi[maxn+10],fir[mod+10],ne[mod+10],val[mod+10],ans[mod+10],tot,num;int sum1(int n){ return (LL)n*(n+1)/2%p;}int sum2(int n){ int x=n,y=n+1,z=2*n+1; if (x%2==0) x/=2; else y/=2; if (x%3==0) x/=3; else if (y%3==0) y/=3; else z/=3; return (LL)x*y%p*z%p;}int find(int n,int &ret){ for (int i=fir[n%mod];i;i=ne[i]) if (val[i]==n) { ret=ans[i]; return 1; } return 0;}void ins(int n,int ret){ if (tot>mod) return; int x=n%mod; tot++; ne[tot]=fir[x]; fir[x]=tot; val[tot]=n; ans[tot]=ret;}int solve(int n){ if (n<=maxn) return phi[n]; int ret; if (find(n,ret)) return ret; ret=sum2(n); for (int i=2,j;i<=n;i=j+1) { j=n/(n/i); ret=dec(ret,(LL)dec(sum1(j),sum1(i-1))*solve(n/i)%p); } ins(n,ret); return ret;}int main(){ phi[1]=1; for (int i=2;i<=maxn;i++) { if (!phi[i]) { prm[++num]=i; phi[i]=i-1; } for (int j=1;j<=num&&(LL)i*prm[j]<=maxn;j++) if (i%prm[j]) phi[i*prm[j]]=phi[i]*(prm[j]-1); else { phi[i*prm[j]]=phi[i]*prm[j]; break; } phi[i]=inc(phi[i-1],(LL)i*phi[i]%p); } int n; scanf("%d",&n); printf("1\n%d\n",solve(n));}
高等数学
- 矩阵求逆
bzoj4128 Matrix【2017.5.18】
#include<cstdio>#include<cmath>#include<map>#include<algorithm>using namespace std;#define LL unsigned long longconst int maxn=75,r=131;int n,p,m;map<LL,int> mp;int inc(int x,int y){ x+=y;return x>=p?x-p:x;}int dec(int x,int y){ x-=y;return x<0?x+p:x;}int inverse(int x){ int ret=1; for (int k=p-2;k;k>>=1,x=x*x%p) if (k&1) ret=ret*x%p; return ret;}struct mat{ int a[maxn][maxn]; LL h; void get() { h=0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) h=h*r+a[i][j]; } void rd() { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) scanf("%d",&a[i][j]); get(); } void init() { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=(i==j); get(); } mat operator * (const mat &m) const { mat ret; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { ret.a[i][j]=0; for (int k=1;k<=n;k++) ret.a[i][j]=inc(ret.a[i][j],a[i][k]*m.a[k][j]%p); } ret.get(); return ret; } mat inv() { mat ret; int x,t; ret.init(); for (int i=1;i<=n;i++) { x=0; for (int j=i;j<=n;j++) if (a[j][i]) { x=j; break; } if (x!=i) for (int j=1;j<=n;j++) { swap(a[i][j],a[x][j]); swap(ret.a[i][j],ret.a[x][j]); } t=inverse(a[i][i]); for (int j=1;j<=n;j++) { a[i][j]=a[i][j]*t%p; ret.a[i][j]=ret.a[i][j]*t%p; } for (int j=1;j<=n;j++) if (j!=i) { t=a[j][i]; for (int k=1;k<=n;k++) { a[j][k]=dec(a[j][k],a[i][k]*t%p); ret.a[j][k]=dec(ret.a[j][k],ret.a[i][k]*t%p); } } } ret.get(); return ret; }}a,b,c;int main(){ scanf("%d%d",&n,&p); a.rd(); b.rd(); m=sqrt(p); c.init(); for (int i=0;i<m;i++) { if (!mp.count(c.h)) mp[c.h]=i; c=c*a; if (b.h==c.h) { printf("%d\n",i+1); return 0; } } c=c.inv(); for (int i=1;;i++) { b=b*c; if (mp.count(b.h)) { printf("%d\n",i*m+mp[b.h]); return 0; } }}
O(k2logn) 递推
bzoj4161 Shlw loves matrixI【2017.5.18】
#include<cstdio>#include<algorithm>using namespace std;#define LL long longconst int maxk=4010,p=1000000007;int n,k,f[maxk],h[maxk];int inc(int x,int y){ x+=y;return x>=p?x-p:x;}int dec(int x,int y){ x-=y;return x<0?x+p:x;}struct mat{ int a[maxk]; mat operator * (const mat &m) const { mat ret; for (int i=0;i<=2*k-2;i++) ret.a[i]=0; for (int i=0;i<k;i++) for (int j=0;j<k;j++) ret.a[i+j]=inc(ret.a[i+j],(LL)a[i]*m.a[j]%p); for (int i=2*k-2;i>=k;i--) for (int j=1;j<=k;j++) ret.a[i-j]=inc(ret.a[i-j],(LL)ret.a[i]*f[j]%p); return ret; }}a,b;int main(){ int ans=0; scanf("%d%d",&n,&k); for (int i=1;i<=k;i++) { scanf("%d",&f[i]); f[i]=dec(f[i],0); } for (int i=0;i<k;i++) { scanf("%d",&h[i]); h[i]=dec(h[i],0); } a.a[1]=1; b.a[0]=1; for (int i=n-k+1;i;i>>=1,a=a*a) if (i&1) b=b*a; for (int i=k;i<=2*k-2;i++) for (int j=1;j<=k;j++) h[i]=inc(h[i],(LL)h[i-j]*f[j]%p); for (int i=0;i<k;i++) ans=inc(ans,(LL)b.a[i]*h[k+i-1]%p); printf("%d\n",ans);}
【2017.7.15】
#include<cstdio>#include<algorithm>using namespace std;#define LL long longconst int p=1000000007,maxk=4010;int inc(int x,int y){ x+=y; return x>=p?x-p:x;}int f[maxk],h[maxk],k,n;struct mat{ int a[maxk]; mat operator * (const mat &m) const { mat ret; for (int i=0;i<=2*k-2;i++) ret.a[i]=0; for (int i=0;i<k;i++) for (int j=0;j<k;j++) ret.a[i+j]=inc(ret.a[i+j],(LL)a[i]*m.a[j]%p); for (int i=2*k-2;i>=k;i--) { for (int j=1;j<=k;j++) ret.a[i-j]=inc(ret.a[i-j],(LL)ret.a[i]*f[j]%p); ret.a[i]=0; } return ret; }}base,res;int main(){ //freopen("d.in","r",stdin); int ans=0; scanf("%d%d",&n,&k); for (int i=1;i<=k;i++) { scanf("%d",&f[i]); if (f[i]<0) f[i]+=p; } for (int i=0;i<k;i++) { scanf("%d",&h[i]); if (h[i]<0) h[i]+=p; } base.a[1]=1; res.a[0]=1; for (n-=k-1;n;n>>=1,base=base*base) if (n&1) res=res*base; for (int i=k;i<=2*k-2;i++) for (int j=1;j<=k;j++) h[i]=inc(h[i],(LL)f[j]*h[i-j]%p); for (int i=0;i<k;i++) ans=inc(ans,(LL)res.a[i]*h[k+i-1]%p); printf("%d\n",ans);}
- 矩阵树定理
【HEOI2015】bzoi4031 小Z的房间【2017.5.18】
#include<cstdio>#include<algorithm>using namespace std;#define LL long longconst int maxn=110,maxl=15,p=1000000000;char map[maxl][maxl];int id[maxl][maxl],a[maxn][maxn],r,c,n;int main(){ int flag=0,x,y,t,ans=1; scanf("%d%d",&r,&c); for (int i=1;i<=r;i++) { scanf("%s",map[i]+1); for (int j=1;j<=c;j++) if (map[i][j]=='.') id[i][j]=++n; } for (int i=1;i<=r;i++) for (int j=1;j<=c;j++) if (map[i][j]=='.') { x=id[i][j]; if (i<r&&map[i+1][j]=='.') { y=id[i+1][j]; a[x][y]--; a[y][x]--; a[x][x]++; a[y][y]++; } if (j<c&&map[i][j+1]=='.') { y=id[i][j+1]; a[x][y]--; a[y][x]--; a[x][x]++; a[y][y]++; } } for (int i=1;i<n;i++) for (int j=1;j<n;j++) if (a[i][j]<0) a[i][j]+=p; for (int i=1;i<n;i++) { x=0; for (int j=i;j<n;j++) if (a[j][i]) { x=j; break; } if (!x) continue; if (x!=i) { flag^=1; for (int j=1;j<n;j++) swap(a[i][j],a[x][j]); } for (int j=i+1;j<n;j++) while (a[j][i]) { if (a[j][i]<a[i][i]) { flag^=1; for (int k=1;k<n;k++) swap(a[j][k],a[i][k]); } t=a[j][i]/a[i][i]; for (int k=1;k<n;k++) a[j][k]=(a[j][k]-(LL)a[i][k]*t%p+p)%p; } } for (int i=1;i<n;i++) ans=(LL)ans*a[i][i]%p; if (flag) ans=(p-ans)%p; printf("%d\n",ans);}
- FFT
bzoj2179 FFT快速傅立叶(FFT)【2017.4.19】
#include<cstdio>#include<cmath>#include<algorithm>using namespace std;const double pi=acos(-1);struct Complex{ double x,y; Complex operator + (const Complex &c) const { return (Complex){x+c.x,y+c.y}; } Complex operator - (const Complex &c) const { return (Complex){x-c.x,y-c.y}; } Complex operator * (const Complex &c) const { return (Complex){x*c.x-y*c.y,x*c.y+y*c.x}; }}a[200010],b[200010],w[200010],t1,t2;char s[200010];int rev[200010],ans[200010],l,m;void fft(Complex *a,int fl){ int x; for (int i=0;i<l;i++) if (rev[i]>i) swap(a[i],a[rev[i]]); for (int i=1;i<=m;i++) for (int j=0;j<l;j+=1<<i) { x=0; for (int k=j;k<(j+(1<<i-1));k++) { t1=a[k]; t2=a[k+(1<<i-1)]; a[k]=t1+t2*w[x]; a[k+(1<<i-1)]=t1-t2*w[x]; x+=fl*(1<<m-i); if (x<0) x+=l; } }}int main(){ int n,nn; scanf("%d",&n); scanf("%s",s); for (int i=0;i<n;i++) a[i].x=s[n-i-1]-'0'; scanf("%s",s); for (int i=0;i<n;i++) b[i].x=s[n-i-1]-'0'; while ((1<<m)<n*2) m++; l=1<<m; w[0]=(Complex){1,0}; w[1]=(Complex){cos(2*pi/l),sin(2*pi/l)}; for (int i=2;i<l;i++) { w[i]=w[i/2]*w[i/2]; if (i&1) w[i]=w[i]*w[1]; } for (int i=0;i<l;i++) for (int j=0;j<m;j++) rev[i]|=((i>>j)&1)<<m-j-1; fft(a,1); fft(b,1); for (int i=0;i<l;i++) a[i]=a[i]*b[i]; fft(a,-1); for (int i=0;i<l;i++) ans[i]=int(a[i].x/l+0.5); for (int i=0;i<2*n-2;i++) { ans[i+1]+=ans[i]/10; ans[i]%=10; } nn=2*n-1; while (!ans[nn-1]) nn--; for (int i=nn-1;i>=0;i--) printf("%d",ans[i]);}
【ZJOI2014】bzoj3527 力【2017.5.18】
#include<cstdio>#include<cmath>#include<algorithm>using namespace std;const int maxn=800010;const double pi=acos(-1);struct Complex{ double a,b; Complex operator + (const Complex &c) const { return (Complex){a+c.a,b+c.b}; } Complex operator - (const Complex &c) const { return (Complex){a-c.a,b-c.b}; } Complex operator * (const Complex &c) const { return (Complex){a*c.a-b*c.b,a*c.b+b*c.a}; }}w[maxn],a[maxn],b[maxn],t1,t2;int rev[maxn],n,l,t;void fft(Complex *a,int flag){ int x; for (int i=0;i<l;i++) if (rev[i]>i) swap(a[i],a[rev[i]]); for (int i=1;i<=t;i++) for (int j=0;j<l;j+=1<<i) { x=0; for (int k=j;k<j+(1<<i-1);k++) { t1=a[k]; t2=a[k+(1<<i-1)]; a[k]=t1+t2*w[x]; a[k+(1<<i-1)]=t1-t2*w[x]; x+=flag*(1<<t-i); if (x<0) x+=l; } }}int main(){ scanf("%d",&n); for (int i=0;i<n;i++) scanf("%lf",&a[i].a); for (int i=0;i<n-1;i++) b[i].a=-1/((double)(n-i-1)*(n-i-1)); for (int i=n;i<2*n-1;i++) b[i].a=1/((double)(i-n+1)*(i-n+1)); l=1,t=0; while (l<4*n-3) l<<=1,t++; for (int i=0;i<l;i++) w[i]=(Complex){cos(2*pi*i/l),sin(2*pi*i/l)}; for (int i=0;i<l;i++) for (int j=0;j<t;j++) rev[i]|=((i>>j)&1)<<(t-j-1); fft(a,1); fft(b,1); for (int i=0;i<l;i++) a[i]=a[i]*b[i]; fft(a,-1); for (int i=n-1;i<2*n-1;i++) printf("%.3f\n",a[i].a/l);}
- 辛普森自适应积分
计算几何
- 射线法
- 凸包
- 旋转卡壳
- 半平面交
图论
- 树链剖分
- LCT
【HNOI2010】bzoj2002 弹飞绵羊
#include<cstdio>#include<algorithm>using namespace std;const int maxn=400010;int rd(){ int x=0; char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x;}int fa[maxn],son[maxn][2],siz[maxn],a[maxn],inv[maxn],sta[maxn],n;void down(int x){ if (inv[x]) { inv[x]=0; swap(son[x][0],son[x][1]); if (son[x][0]) inv[son[x][0]]^=1; if (son[x][1]) inv[son[x][1]]^=1; }}void up(int x){ down(x); siz[x]=siz[son[x][0]]+siz[son[x][1]]+1;}int isroot(int x){ return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;}void rot(int u,int f){ int v=son[u][f],x=son[v][f^1],y=fa[u]; if (son[y][0]==u) son[y][0]=v; if (son[y][1]==u) son[y][1]=v; fa[v]=y; son[v][f^1]=u; fa[u]=v; son[u][f]=x; if (x) fa[x]=u; up(u); up(v);}void splay(int u){ int top=0,x,y,fx,fy; for (int i=u;;i=fa[i]) { sta[++top]=i; if (isroot(i)) break; } for (;top;top--) down(sta[top]); while (!isroot(u)) { x=fa[u]; fx=son[x][1]==u; if (isroot(x)) rot(x,fx); else { y=fa[x]; fy=son[y][1]==x; if (fx==fy) rot(y,fy),rot(x,fx); else rot(x,fx),rot(y,fy); } }}void access(int u){ int v=0; while (u) { splay(u); son[u][1]=v; up(u); v=u; u=fa[u]; }}void makeroot(int x){ access(x); splay(x); inv[x]^=1; up(x);}void link(int x,int y){ makeroot(y); fa[x]=y;}void cut(int x,int y){ makeroot(y); access(x); splay(x); son[x][0]=fa[y]=0; up(x);}int qry(int x){ makeroot(n+1); access(x); splay(x); return siz[x]-1;}int main(){ int q,opt,x,y; n=rd(); for (int i=1;i<=n;i++) siz[i]=1; for (int i=1;i<=n;i++) { a[i]=rd(); if (i+a[i]>n) a[i]=n-i+1; link(i,i+a[i]); } q=rd(); while (q--) { opt=rd(); if (opt==1) printf("%d\n",qry(rd()+1)); else { x=rd()+1; y=rd(); cut(x,x+a[x]); a[x]=y; if (x+a[x]>n) a[x]=n-x+1; link(x,x+a[x]); } }}
bzoj2631 tree【2017.5.16】
#include<cstdio>#include<algorithm>using namespace std;#define UI unsigned intconst int maxn=200010,p=51061;int rd(){ int x=0; char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x;}char rdc(){ char c=getchar(); while (c!='+'&&c!='*'&&c!='/'&&c!='-') c=getchar(); return c;}int inc(int x,int y){ x+=y;return x>=p?x-p:x;}int son[maxn][2],fa[maxn],tagp[maxn],tagm[maxn],sum[maxn],val[maxn],siz[maxn],inv[maxn],sta[maxn],n;int is(int u){ return son[fa[u]][0]!=u&&son[fa[u]][1]!=u;}void down(int u){ int v; if (inv[u]) { inv[u]=0; swap(son[u][0],son[u][1]); if (v=son[u][0]) inv[v]^=1; if (v=son[u][1]) inv[v]^=1; } if (tagm[u]!=1) { val[u]=(UI)val[u]*tagm[u]%p; sum[u]=(UI)sum[u]*tagm[u]%p; if (v=son[u][0]) { tagm[v]=(UI)tagm[v]*tagm[u]%p; tagp[v]=(UI)tagp[v]*tagm[u]%p; } if (v=son[u][1]) { tagm[v]=(UI)tagm[v]*tagm[u]%p; tagp[v]=(UI)tagp[v]*tagm[u]%p; } tagm[u]=1; } if (tagp[u]) { val[u]=inc(val[u],tagp[u]); sum[u]=inc(sum[u],(UI)tagp[u]*siz[u]%p); if (v=son[u][0]) tagp[v]=inc(tagp[v],tagp[u]); if (v=son[u][1]) tagp[v]=inc(tagp[v],tagp[u]); tagp[u]=0; }}void up(int u){ down(u); if (son[u][0]) down(son[u][0]); if (son[u][1]) down(son[u][1]); int v; sum[u]=val[u]; siz[u]=1; if (v=son[u][0]) { sum[u]=inc(sum[u],sum[v]); siz[u]=siz[u]+siz[v]; } if (v=son[u][1]) { sum[u]=inc(sum[u],sum[v]); siz[u]=siz[u]+siz[v]; }}void rot(int u,int f){ int v=son[u][f],x=son[v][f^1],y=fa[u]; if (!is(u)) son[y][son[y][1]==u]=v; fa[v]=y; son[v][f^1]=u; fa[u]=v; son[u][f]=x; if (x) fa[x]=u; up(u); up(v);}void splay(int u){ int v,x,y,xx,yy,t=u,top=0; while (1) { sta[++top]=t; if (is(t)) break; t=fa[t]; } for (;top;top--) down(sta[top]); while (!is(u)) { x=fa[u]; xx=son[x][1]==u; if (is(x)) rot(x,xx); else { y=fa[x]; yy=son[y][1]==x; if (xx==yy) rot(y,yy),rot(x,xx); else rot(x,xx),rot(y,yy); } }}void access(int u){ int v=0,t=u; while (u) { splay(u); son[u][1]=v; up(u); v=u; u=fa[u]; } splay(t);}void make(int u){ access(u); inv[u]^=1; up(u);}void link(int u,int v){ make(u); fa[u]=v;}void cut(int u,int v){ make(u); access(v); son[v][0]=fa[u]=0; up(v);}int query(int u,int v){ make(u); access(v); return sum[v];}void modip(int u,int v,int x){ make(u); access(v); tagp[v]=inc(tagp[v],x);}void modim(int u,int v,int x){ make(u); access(v); tagp[v]=(UI)tagp[v]*x%p; tagm[v]=(UI)tagm[v]*x%p;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); char c; int u,v,x,y,q; n=rd(); q=rd(); for (int i=1;i<=n;i++) sum[i]=val[i]=tagm[i]=siz[i]=1; for (int i=1;i<n;i++) { u=rd(); v=rd(); link(u,v); } while (q--) { c=rdc(); u=rd(); v=rd(); if (c=='/') printf("%d\n",query(u,v)); else { x=rd(); if (c=='+') modip(u,v,x); else if (c=='*') modim(u,v,x); else { y=rd(); cut(u,v); link(x,y); } } }}
- 点分治
poj1741 Tree【2017.5.16】
#include<cstdio>#include<algorithm>using namespace std;const int maxn=10010;struct node{ int bel,dis; bool operator < (const node &n) const { return dis<n.dis; }}a[maxn];int fir[maxn],vis[maxn],ne[2*maxn],to[2*maxn],w[2*maxn],size[maxn],val[maxn],sum[maxn],rt,n,m,ans,S,tot;void add(int num,int u,int v,int x){ ne[num]=fir[u]; fir[u]=num; to[num]=v; w[num]=x;}void dfs1(int u,int fa){ size[u]=1; val[u]=0; for (int i=fir[u];i;i=ne[i]) if (to[i]!=fa&&!vis[to[i]]) { dfs1(to[i],u); size[u]+=size[to[i]]; val[u]=max(val[u],size[to[i]]); } val[u]=max(val[u],S-size[u]); if (rt==-1||val[u]<val[rt]) rt=u;}void dfs2(int u,int fa,int b,int d){ size[u]=1; a[++tot]=(node){b,d}; for (int i=fir[u];i;i=ne[i]) if (to[i]!=fa&&!vis[to[i]]) { dfs2(to[i],u,b,d+w[i]); size[u]+=size[to[i]]; }}void solve(int u){ int r,num=0,s=0; rt=-1; dfs1(u,-1); r=rt; a[tot=1]=(node){0,0}; for (int i=fir[r];i;i=ne[i]) if (!vis[to[i]]) dfs2(to[i],r,++num,w[i]); sort(a+1,a+tot+1); for (int i=0;i<=num;i++) sum[i]=0; for (int i=tot,j=0;i;i--) { while (j<tot&&a[j+1].dis+a[i].dis<=m) sum[a[++j].bel]++; ans+=j-sum[a[i].bel]; } vis[r]=1; for (int i=fir[r];i;i=ne[i]) if (!vis[to[i]]) { S=size[to[i]]; solve(to[i]); }}void solve(){ int u,v,x; for (int i=1;i<=n;i++) fir[i]=vis[i]=0; ans=0; for (int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&x); add(i*2,u,v,x); add(i*2+1,v,u,x); } S=n; solve(1); printf("%d\n",ans/2);}int main(){ while (scanf("%d%d",&n,&m)&&n) solve();}
- 边分治
- 动态点分治
【ZJOI2007】bzoj1095 捉迷藏【2017.5.18】
#include<cstdio>#include<queue>#include<algorithm>using namespace std;const int maxn=100010;struct heap{ priority_queue<int> a,b; void ins(int x) { a.push(x); } void del(int x) { b.push(x); } int size() { return a.size()-b.size(); } int top() { while (!b.empty()&&a.top()==b.top()) { a.pop(); b.pop(); } return a.top(); } int get() { int x=top(); del(x); int y=top(); ins(x); return x+y; }}q1[maxn],q2[maxn],q3;int fir[maxn],ne[2*maxn],to[2*maxn],vis[maxn],size[maxn],val[maxn],fa[maxn],flag[maxn],mn[2*maxn][20],pos[maxn],dep[maxn],log[2*maxn],n,rt,clo;void add(int num,int u,int v){ ne[num]=fir[u]; fir[u]=num; to[num]=v;}void dfs0(int u,int fa,int d){ dep[u]=d; mn[pos[u]=++clo][0]=d; for (int i=fir[u];i;i=ne[i]) if (to[i]!=fa) { dfs0(to[i],u,d+1); mn[++clo][0]=d; }}void dfs1(int u,int fa){ size[u]=1; for (int i=fir[u];i;i=ne[i]) if (!vis[to[i]]&&to[i]!=fa) { dfs1(to[i],u); size[u]+=size[to[i]]; }}int dfs2(int u,int fa,int S){ int ret=-1,x; val[u]=S-size[u]; for (int i=fir[u];i;i=ne[i]) if (!vis[to[i]]&&to[i]!=fa) { x=dfs2(to[i],u,S); val[u]=max(val[u],size[to[i]]); if (ret==-1||val[x]<val[ret]) ret=x; } if (ret==-1||val[u]<val[ret]) ret=u; return ret;}void dfs3(int u,int fa,int bel,int dis){ q1[bel].ins(dis); for (int i=fir[u];i;i=ne[i]) if (!vis[to[i]]&&to[i]!=fa) dfs3(to[i],u,bel,dis+1);}int solve(int u){ dfs1(u,-1); int r=dfs2(u,-1,size[u]),x; vis[r]=1; for (int i=fir[r];i;i=ne[i]) if (!vis[to[i]]) { x=solve(to[i]); dfs3(to[i],r,x,1); fa[x]=r; q2[r].ins(q1[x].top()); } q2[r].ins(0); vis[r]=0; if (q2[r].size()>=2) q3.ins(q2[r].get()); return r;}int dis(int u,int v){ int x=pos[u],y=pos[v],k; if (x>y) swap(x,y); k=log[y-x+1]; return dep[u]+dep[v]-2*min(mn[x][k],mn[y-(1<<k)+1][k]);}void ins(int u){ if (q2[u].size()>=2) q3.del(q2[u].get()); q2[u].ins(0); if (q2[u].size()>=2) q3.ins(q2[u].get()); for (int i=u;fa[i];i=fa[i]) { if (q2[fa[i]].size()>=2) q3.del(q2[fa[i]].get()); if (q1[i].size()) q2[fa[i]].del(q1[i].top()); q1[i].ins(dis(u,fa[i])); if (q1[i].size()) q2[fa[i]].ins(q1[i].top()); if (q2[fa[i]].size()>=2) q3.ins(q2[fa[i]].get()); }}void del(int u){ if (q2[u].size()>=2) q3.del(q2[u].get()); q2[u].del(0); if (q2[u].size()>=2) q3.ins(q2[u].get()); for (int i=u;fa[i];i=fa[i]) { if (q2[fa[i]].size()>=2) q3.del(q2[fa[i]].get()); if (q1[i].size()) q2[fa[i]].del(q1[i].top()); q1[i].del(dis(u,fa[i])); //printf("%d\n",q1[i].size()); if (q1[i].size()) q2[fa[i]].ins(q1[i].top()); if (q2[fa[i]].size()>=2) q3.ins(q2[fa[i]].get()); }}int main(){ int u,v,q,now; char c[3]; scanf("%d",&n); for (int i=1;i<n;i++) { scanf("%d%d",&u,&v); add(i*2,u,v); add(i*2+1,v,u); } dfs0(1,-1,1); for (int i=1;(1<<i)<=clo;i++) log[1<<i]=i; for (int i=3;i<=clo;i++) if (!log[i]) log[i]=log[i-1]; for (int k=1;k<=log[clo];k++) for (int i=1;i+(1<<k)-1<=clo;i++) mn[i][k]=min(mn[i][k-1],mn[i+(1<<k-1)][k-1]); rt=solve(1); now=n; scanf("%d",&q); while (q--) { scanf("%s",c); if (c[0]=='C') { scanf("%d",&u); if (flag[u]) ins(u),now++; else del(u),now--; flag[u]^=1; } else { if (now==0) printf("-1\n"); else if (now==1) printf("0\n"); else printf("%d\n",q3.top()); } }}
- 2-SAT
poj3678 Katu Puzzle【2017.5.19】
#include<cstdio>#include<algorithm>using namespace std;const int maxn=2010,maxm=2000010;int fir[maxn],ne[maxm],to[maxm],dfn[maxn],low[maxn],sta[maxn],bel[maxn],in[maxn],n,m,num,clo,tot,top;void add(int u,int v){ num++; ne[num]=fir[u]; fir[u]=num; to[num]=v;}void dfs(int u){ int x; dfn[u]=low[u]=++clo; sta[++top]=u; in[u]=1; for (int i=fir[u];i;i=ne[i]) if (!dfn[to[i]]) { dfs(to[i]); low[u]=min(low[u],low[to[i]]); } else if (in[to[i]]) low[u]=min(low[u],dfn[to[i]]); if (low[u]==dfn[u]) { tot++; do { x=sta[top--]; bel[x]=tot; in[x]=0; } while (x!=u); }}int main(){ int u,v,x; char s[10]; scanf("%d%d",&n,&m); while (m--) { scanf("%d%d%d%s",&u,&v,&x,s); switch (s[0]) { case 'A': if (x==0) { add(v*2+1,u*2); add(u*2+1,v*2); } else { add(u*2,u*2+1); add(v*2,v*2+1); } break; case 'O': if (x==0) { add(u*2+1,u*2); add(v*2+1,v*2); } else { add(u*2,v*2+1); add(v*2,u*2+1); } break; case 'X': if (x==0) { add(u*2,v*2); add(v*2,u*2); add(u*2+1,v*2+1); add(v*2+1,u*2+1); } else { add(u*2,v*2+1); add(v*2,u*2+1); add(u*2+1,v*2); add(v*2+1,u*2); } break; } } for (int i=0;i<n*2;i++) if (!dfn[i]) dfs(i); for (int i=0;i<n;i++) if (bel[i*2]==bel[i*2+1]) { printf("NO\n"); return 0; } printf("YES\n");}
动态规划
- 斜率优化dp
【APIO2010】bzoj1911 特别行动队
#include<cstdio>#include<algorithm>using namespace std;#define LL long longconst int maxn=1000010;int rd(){ int x=0,f=1; char c=getchar(); while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); } while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f;}LL dp[maxn],s[maxn],h[maxn],g[maxn],a,b,c;int que[maxn],n;double get(int i,int j){ return (double)(h[j]-h[i])/(s[j]-s[i]);}int main(){ int hd=1,tl=1; n=rd(); a=rd(); b=rd(); c=rd(); for (int i=1;i<=n;i++) s[i]=s[i-1]+rd(); for (int i=1;i<=n;i++) { while (hd<tl&&get(que[hd],que[hd+1])<=-2*a*s[i]) hd++; dp[i]=dp[que[hd]]+a*(s[i]-s[que[hd]])*(s[i]-s[que[hd]])+b*(s[i]-s[que[hd]])+c; h[i]=-a*s[i]*s[i]+b*s[i]-dp[i]; while (hd<tl&&get(que[tl-1],que[tl])>=get(que[tl],i)) tl--; que[++tl]=i; } printf("%lld\n",dp[n]);}
- 插头dp
【SCOI2011】bzoj2331 地板【2017.5.19】
#include<cstdio>#include<algorithm>using namespace std;const int p=20110520;char mp[110][110];int dp[2][4200010],last[4200010],f[2][4200010],r,c,clo,tot,y;int inc(int x,int y){ x+=y;return x>=p?x-p:x;}void upd(int x){ if (last[x]==clo+1) dp[clo&1^1][x]=inc(dp[clo&1^1][x],y); else { last[x]=clo+1; f[clo&1^1][++tot]=x; dp[clo&1^1][x]=y; }}int main(){ int x,t1,ans=0; scanf("%d%d",&r,&c); for (int i=1;i<=r;i++) scanf("%s",mp[i]+1); if (r<c) { for (int i=1;i<=c;i++) for (int j=i+1;j<=c;j++) swap(mp[i][j],mp[j][i]); swap(r,c); } f[1][tot=1]=0; dp[1][0]=1; for (int i=1;i<=r;i++) for (int j=1;j<=c;j++) { clo++; t1=tot; tot=0; for (int k=1;k<=t1;k++) { x=f[clo&1][k]; y=dp[clo&1][x]; if (mp[i][j]=='*') { if (!(x&1)&&!((x>>2)&1)) upd(x>>2); continue; } if (!(x&1)) { if (!(x&4)) { upd((x>>2)|(1<<2*c)); if (j<c) { upd((x>>2)|1); upd((x>>2)|3|(3<<2*c)); } } else if (!(x&8)) { upd(((x>>2)^1)|(1<<2*c)); if (j<c) upd((x>>2)|3); } else { upd((x>>2)^3); upd(((x>>2)^3)|(3<<2*c)); } } else if (!(x&2)) { if (!(x&4)) { if (j<c) upd((x>>2)|1); upd((x>>2)|(3<<2*c)); } else if (!(x&8)) upd((x>>2)^1); } else { if (!(x&4)) { upd(x>>2); if (j<c) upd((x>>2)|3); } } } } printf("%d\n",last[0]==clo+1?dp[clo&1^1][0]:0);}
- 数位dp
- 四边形不等式
其他算法
- CDQ分治
bzoj3262 陌上花开【2017.5.16】
#include<cstdio>#include<algorithm>using namespace std;const int maxn=100010,maxm=200010;int rd(){ int x=0; char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x;}struct flower{ int a,b,c,res,num; bool operator < (const flower &f) const { if (a!=f.a) return a<f.a; if (b!=f.b) return b<f.b; return c<f.c; }}a[maxn],b[maxn];int s[maxm],ans[maxn],n,m;void add(int k,int x){ for (;k<=m;k+=k&-k) s[k]+=x;}int qry(int k){ int ret=0; for (;k;k-=k&-k) ret+=s[k]; return ret;}void solve(int l,int r){ if (l==r) return; int mid=(l+r)/2; solve(l,mid); solve(mid+1,r); for (int i=l;i<=r;i++) b[i]=a[i]; for (int i=l,j=mid+1,now=l;i<=mid||j<=r;) if (j>r||(i<=mid&&b[i].b<=b[j].b)) { add(b[i].c,b[i].num); a[now++]=b[i++]; } else { b[j].res+=qry(b[j].c); a[now++]=b[j++]; } for (int i=l;i<=mid;i++) add(b[i].c,-b[i].num);}int main(){ int N=1; n=rd(); m=rd(); for (int i=1;i<=n;i++) { a[i].a=rd(); a[i].b=rd(); a[i].c=rd(); a[i].num=1; } sort(a+1,a+n+1); b[1]=a[1]; for (int i=2;i<=n;i++) if (a[i-1]<a[i]) b[++N]=a[i]; else b[N].num++; for (int i=1;i<=N;i++) a[i]=b[i]; solve(1,N); for (int i=1;i<=N;i++) ans[a[i].res+a[i].num-1]+=a[i].num; for (int i=0;i<n;i++) printf("%d\n",ans[i]);}
- 整体二分
bzoj2738 矩阵乘法【2017.5.16】
#include<cstdio>#include<algorithm>using namespace std;const int maxn=510,maxq=60010;int rd(){ int x=0; char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x;}struct qry{ int x1,y1,x2,y2,id,res,k;}f[maxq],g[maxq];struct node{ int x,y,v; bool operator < (const node &n) const { return v<n.v; }}a[maxn*maxn];int s[maxn][maxn],ans[maxq],n,q,tot;void add(node a){ for (int i=a.x;i<=n;i+=i&-i) for (int j=a.y;j<=n;j+=j&-j) s[i][j]++;}void dec(node a){ for (int i=a.x;i<=n;i+=i&-i) for (int j=a.y;j<=n;j+=j&-j) s[i][j]--;}int query(qry a){ int ret=0; for (int i=a.x2;i;i-=i&-i) for (int j=a.y2;j;j-=j&-j) ret+=s[i][j]; for (int i=a.x1-1;i;i-=i&-i) for (int j=a.y2;j;j-=j&-j) ret-=s[i][j]; for (int i=a.x2;i;i-=i&-i) for (int j=a.y1-1;j;j-=j&-j) ret-=s[i][j]; for (int i=a.x1-1;i;i-=i&-i) for (int j=a.y1-1;j;j-=j&-j) ret+=s[i][j]; return ret;}void solve(int l,int r,int L,int R){ if (L==R) { for (int i=l;i<=r;i++) f[i].res=a[L].v; return; } int mid=(L+R)/2,m=r,x; for (int i=L;i<=mid;i++) add(a[i]); for (int i=l,j=l,k=r;i<=r;i++) { x=query(f[i]); if (f[i].k<=x) g[j++]=f[i]; else { f[i].k-=x; g[k--]=f[i]; m=k; } } for (int i=L;i<=mid;i++) dec(a[i]); for (int i=l;i<=r;i++) f[i]=g[i]; solve(l,m,L,mid); solve(m+1,r,mid+1,R);}int main(){ int x1,y1,x2,y2,k; n=rd(); q=rd(); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[++tot]=(node){i,j,rd()}; for (int i=1;i<=q;i++) { x1=rd(); y1=rd(); x2=rd(); y2=rd(); k=rd(); f[i]=(qry){x1,y1,x2,y2,i,0,k}; } sort(a+1,a+tot+1); solve(1,q,1,tot); for (int i=1;i<=q;i++) ans[f[i].id]=f[i].res; for (int i=1;i<=q;i++) printf("%d\n",ans[i]);}
【ZJOI2013】bzoj3110 K大数查询【2017.7.14】
#include<cstdio>#include<algorithm>using namespace std;#define UI unsigned intconst int maxn=50010,maxt=2000000;int rdi(){ int x=0,f=1; char c=getchar(); while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); } while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f;}UI rdu(){ UI x=0; char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x;}struct str{ int l,r,id,f; UI x;}a[maxn],b[maxn],c[maxn];UI sum[maxt];int n,m,o,val[maxn],ord[maxn],ans[maxn],tag[maxt];void down(int u,int L,int R){ if (L<R) { tag[u*2]+=tag[u]; tag[u*2+1]+=tag[u]; } sum[u]+=(UI)tag[u]*(R-L+1); tag[u]=0;}UI qry(int u,int L,int R,int l,int r){ down(u,L,R); if (l<=L&&R<=r) return sum[u]; int mid=(L+R)/2; UI ret=0; if (l<=mid) ret=qry(u*2,L,mid,l,r); if (r>mid) ret+=qry(u*2+1,mid+1,R,l,r); return ret;}void modi(int u,int L,int R,int l,int r,int x){ if (l<=L&&R<=r) { tag[u]+=x; return; } down(u,L,R); int mid=(L+R)/2; if (l<=mid) modi(u*2,L,mid,l,r,x); if (r>mid) modi(u*2+1,mid+1,R,l,r,x); down(u*2,L,mid); down(u*2+1,mid+1,R); sum[u]=sum[u*2]+sum[u*2+1];}void solve(int L,int R,int l,int r){ if (l==r) { for (int i=L;i<=R;i++) if (a[i].f==2) ans[a[i].id]=l; return; } int mid=(l+r)/2,n1=0,n2=0; UI x; for (int i=L;i<=R;i++) if (a[i].f==1) { if ((int)a[i].x>mid) { modi(1,1,n,a[i].l,a[i].r,1); c[++n2]=a[i]; } else b[++n1]=a[i]; } else { x=qry(1,1,n,a[i].l,a[i].r); if (x>=a[i].x) c[++n2]=a[i]; else { a[i].x-=x; b[++n1]=a[i]; } } for (int i=L;i<=R;i++) if (a[i].f==1&&(int)a[i].x>mid) modi(1,1,n,a[i].l,a[i].r,-1); for (int i=1;i<=n1;i++) a[L+i-1]=b[i]; for (int i=1;i<=n2;i++) a[L+n1+i-1]=c[i]; solve(L,L+n1-1,l,mid); solve(L+n1,R,mid+1,r);}int main(){ //freopen("b.in","r",stdin); //freopen("b.out","w",stdout); n=rdi(); m=rdi(); for (int i=1;i<=m;i++) { a[i].f=rdi(); a[i].l=rdi(); a[i].r=rdi(); if (a[i].f==1) val[i]=ord[++o]=rdi(); else a[i].x=rdu(); a[i].id=i; } sort(ord+1,ord+o+1); o=unique(ord+1,ord+o+1)-ord-1; for (int i=1;i<=m;i++) if (a[i].f==1) a[i].x=lower_bound(ord+1,ord+o+1,val[i])-ord; solve(1,m,1,o); for (int i=1;i<=m;i++) if (ans[i]) printf("%d\n",ord[ans[i]]);}
1 0
- 我的模板库【填坑中】
- 我的模板库
- 我的模板库
- 我用的“模板”
- 我的博客模板
- 我的模板
- 我的XeTeX模板
- 我的 ISAP 模板
- 我的 MCMF 模板
- 我的项目模板
- 我的框架:模板
- 我的模板
- 我的导出模板
- 我的html模板
- 我的模板
- 我的makefile模板
- 我的算法模板
- 我的treap模板
- PlaidCTF CTF 2015 pwn160
- 如何在EditText中设置固定图片——Android移动开发
- 数据结构链表的一些的问题
- ubuntu kylin 16.04 虚拟机安装nvidia375之后系统登陆界面无限循环解决办法
- 装备选择
- 我的模板库【填坑中】
- 递归形式二分查找
- 利用XML文件和Java代码来综合管理设计UI界面,比如
- nginx配置nodejs服务二级域名
- 使用MyBatis进行模糊查询时%到底写哪儿的解决办法
- STL之容器作为形参的传递
- RelativeLayout 的一些相关属性
- swustoj最近对问题(0794)
- QtCharts源码编译安装