模板集合——持续更新中
Posted chty
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板集合——持续更新中相关的知识,希望对你有一定的参考价值。
首先
sro_Cydiater_orz
sro_姬树流_orz
两位开搞模板集合已久的大神
1、对拍
1 @echo off 2 set path=C:\\MinGWStudio\\MinGW\\bin 3 g++ -o makedata.exe makedata.cpp 4 g++ -o right.exe right.cpp 5 g++ -o test.exe test.cpp 6 set path=C:\\Windows\\system32 7 :loop 8 makedata.exe 9 right.exe 10 test.exe 11 fc cout1.out cout2.out 12 if errorlevel==1 pause 13 goto loop
2、fread
1 char buf[1<<15],*fs,*ft; 2 inline char getc() {return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;} 3 inline int read() 4 { 5 int x=0,f=1; char ch=getc(); 6 while(!isdigit(ch)) {if(ch==\'-\') f=-1; ch=getc();} 7 while(isdigit(ch)) {x=x*10+ch-\'0\'; ch=getc();} 8 return x*f; 9 }
3、fwrite
1 char buf[1<<15],*fs=buf,*ft=buf+(1<<15); 2 #define ot(x) (fs==ft?fwrite(buf,1,1<<15,stdout),*(fs=buf)++=x:*fs++=x) 3 inline void print(int x) 4 { 5 if(x<0) {ot(45);x=-x;} 6 static char s[15],*b; b=s; 7 if(!x)*b++=48; 8 for(;x;*b++=x%10+48,x/=10); 9 for(;b--!=s;ot(*b)); 10 }
4、倍增求LCA
1 void dfs(int x,int fa) 2 { 3 anc[x][0]=f[x]; 4 for(int i=1;i<=20;i++) anc[x][i]=anc[anc[x][i-1]][i-1]; 5 for(int i=Link[x];i;i=e[i].next) 6 if(e[i].y!=fa) 7 { 8 f[e[i].y]=x; 9 deep[e[i].y]=deep[x]+1; 10 dfs(e[i].y,x); 11 } 12 } 13 int lca(int x,int y) 14 { 15 if(deep[x]<deep[y]) swap(x,y); 16 for(int i=20;i>=0;i--) if(deep[anc[x][i]]>=deep[y]) x=anc[x][i]; 17 if(x==y) return x; 18 for(int i=20;i>=0;i--) if(anc[x][i]!=anc[y][i]) x=anc[x][i],y=anc[y][i]; 19 return f[x]; 20 }
5、树链剖分
1 void dfs1(int x) 2 { 3 dep[x]=dep[f[x]]+1; size[x]=1; 4 for(int i=a[x];i;i=e[i].next) 5 if(e[i].y!=f[x]&&!f[e[i].y]) 6 { 7 f[e[i].y]=x; 8 dfs1(e[i].y); 9 size[x]+=size[e[i].y]; 10 if(size[son[x]]<size[e[i].y]) son[x]=e[i].y; 11 } 12 } 13 void dfs2(int x) 14 { 15 if(x==son[f[x]])top[x]=top[f[x]]; else top[x]=x; 16 for(int i=a[x];i;i=e[i].next) if(f[e[i].y]==x) dfs2(e[i].y); 17 }
6、Treap
1 struct data{int l,r,v,size,fix,w;}tr[100005]; 2 int n,len,root,ans; 3 void update(int k){tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w;} 4 void rturn(int &k){int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k;tr[t].size=tr[k].size;update(k);k=t;} 5 void lturn(int &k){int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k;tr[t].size=tr[k].size;update(k);k=t;} 6 void insert(int &k,int x) 7 { 8 if(k==0){len++;k=len;tr[k].size=tr[k].w=1;tr[k].v=x;tr[k].fix=rand();return;} 9 tr[k].size++; 10 if(tr[k].v==x)tr[k].w++;//每个结点顺便记录下与该节点相同值的数的个数 11 else if(x>tr[k].v){insert(tr[k].r,x);if(tr[tr[k].r].fix<tr[k].fix)lturn(k);} 12 else {insert(tr[k].l,x);if(tr[tr[k].l].fix<tr[k].fix)rturn(k);} 13 } 14 void del(int &k,int x) 15 { 16 if(k==0)return; 17 if(tr[k].v==x) 18 { 19 if(tr[k].w>1){tr[k].w--;tr[k].size--;return;} 20 if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;//有一个儿子为空 21 else if(tr[tr[k].l].fix<tr[tr[k].r].fix) rturn(k),del(k,x); 22 else lturn(k),del(k,x); 23 } 24 else if(x>tr[k].v) tr[k].size--,del(tr[k].r,x); 25 else tr[k].size--,del(tr[k].l,x); 26 } 27 int rank(int k,int x) 28 { 29 if(k==0) return 0; 30 if(tr[k].v==x) return tr[tr[k].l].size+1; 31 else if(x>tr[k].v) return tr[tr[k].l].size+tr[k].w+rank(tr[k].r,x); 32 else return rank(tr[k].l,x); 33 } 34 int Findkth(int k,int x) 35 { 36 if(k==0)return 0; 37 if(x<=tr[tr[k].l].size) return Findkth(tr[k].l,x); 38 else if(x>tr[tr[k].l].size+tr[k].w) return Findkth(tr[k].r,x-tr[tr[k].l].size-tr[k].w); 39 else return tr[k].v; 40 } 41 void get_before(int k,int x) 42 { 43 if(k==0)return; 44 if(tr[k].v<x) ans=k;get_before(tr[k].r,x); 45 else get_before(tr[k].l,x); 46 } 47 void get_behind(int k,int x) 48 { 49 if(k==0)return; 50 if(tr[k].v>x) ans=k;get_behind(tr[k].l,x); 51 else get_behind(tr[k].r,x); 52 }
7、替罪羊树
1 #define INF 1000000000 2 const double chty=0.75; //平衡常数 3 struct node{int son[2],f,size,v;}tr[100005]; 4 int n,len,root,top,stack[100005]; 5 void init() 6 { 7 len=2; root=1; 8 tr[1].size=2; tr[1].v=-INF; tr[1].son[1]=2; 9 tr[2].size=1; tr[2].v=INF; tr[2].f=1; 10 } 11 bool balance(int x) 12 { 13 double p=tr[x].size*chty; 14 return p>=(double)tr[tr[x].son[0]].size&&p>=(double)tr[tr[x].son[1]].size; 15 } 16 void dfs(int x)//中序遍历 17 { 18 if(!x) return; 19 dfs(tr[x].son[0]); 20 stack[++top]=x; 21 dfs(tr[x].son[1]); 22 } 23 int build(int l,int r) 24 { 25 if(l>r) return 0; 26 int mid=(l+r)/2,x=stack[mid]; 27 tr[tr[x].son[0]=build(l,mid-1)].f=x; 28 tr[tr[x].son[1]=build(mid+1,r)].f=x; 29 tr[x].size=tr[tr[x].son[0]].size+tr[tr[x].son[1]].size+1; 30 return x; 31 } 32 void rebuild(int x) 33 { 34 top=0; dfs(x); 35 int fa=tr[x].f,which=(tr[fa].son[1]==x); 36 int sonroot=build(1,top); 37 tr[tr[fa].son[which]=sonroot].f=fa; 38 if(x==root) root=sonroot; 39 } 40 int find(int v) 41 { 42 int now=root; 43 while(now) 44 { 45 if(v==tr[now].v) return now; 46 else now=tr[now].son[v>tr[now].v]; 47 } 48 } 49 void insert(int v) 50 { 51 int now=root,p=++len; 52 tr[p].v=v; tr[p].size=1;//新开结点 53 while(1) 54 { 55 tr[now].size++; 56 int which=(v>=tr[now].v);//表示p在当前根的哪个子树内 57 if(tr[now].son[which]) now=tr[now].son[which]; 58 else {tr[tr[now].son[which]=p].f=now; break;} 59 } 60 int id=0; 61 for(int i=p;i;i=tr[i].f) if(!balance(i)) id=i;//记录不平衡点 62 if(id) rebuild(id);//重构子树 63 } 64 void del(int x) 65 { 66 if(tr[x].son[0]&&tr[x].son[1]) 67 { 68 int p=tr[x].son[0]; 69 while(tr[p].son[1]) p=tr[p].son[1]; 70 tr[x].v=tr[p].v; x=p; 71 } 72 int Son=(tr[x].son[0])?tr[x].son[0]:tr[x].son[1],which=(tr[tr[x].f].son[1]==x); 73 tr[tr[tr[x].f].son[which]=Son].f=tr[x].f; 74 for(int i=tr[x].f;i;i=tr[i].f) tr[i].size--; 75 if(x==root) root=Son; 76 } 77 int rank(int v) 78 { 79 int now=root,ans=0; 80 while(now) 81 { 82 if(tr[now].v<v) {ans+=tr[tr[now].son[0]].size+1; now=tr[now].son[1];} 83 else now=tr[now].son[0]; 84 } 85 return ans; 86 } 87 int kth(int x) 88 { 89 int now=root; 90 while(1) 91 { 92 if(tr[tr[now].son[0]].size==x-1) return now; 93 else if(tr[tr[now].son[0]].size>=x) now=tr[now].son[0]; 94 else x-=tr[tr[now].son[0]].size+1,now=tr[now].son[1]; 95 } 96 return now; 97 } 98 int before(int v) 99 { 100 int now=root,ans=-INF; 101 while(now) 102 { 103 if(tr[now].v<v) ans=max(ans,tr[now].v),now=tr[now].son[1]; 104 else now=tr[now].son[0]; 105 } 106 return ans; 107 } 108 int after(int v) 109 { 110 int now=root,ans=INF; 111 while(now) 112 { 113 if(tr[now].v>v) ans=min(ans,tr[now].v),now=tr[now].son[0]; 114 else now=tr[now].son[1]; 115 } 116 return ans; 117 }
8、kmp
1 void pre(){int j=0;for(int i=2;i<=m;i++){while(j>0&&b[j+1]!=b[i])j=p[j];if(b[j+1]==b[i])j++;p[i]=j;}} 2 void kmp(){int j=0;for(int i=1;i<=n;i++){while(j>0&&b[j+1]!=a[i])j=p[j];if(b[j+1]==a[i])j++;if(j==m)printf("%d\\n",i-m+1);}
9、AC自动机
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<ctime> 7 #include<algorithm> 8 #include<iomanip> 9 using namespace std; 10 #define MAXN 1000100 11 int n,cnt,q[MAXN],fail[MAXN],end[MAXN],tr[MAXN][26]; 12 char ch[MAXN]; 13 void insert() 14 { 15 int now=0; 16 for(int i=1;i<=strlen(ch+1);i++) 17 { 18 if(!tr[now][ch[i]-\'a\']) tr[now][ch[i]-\'a\']=++cnt; 19 now=tr[now][ch[i]-\'a\']; 20 } 21 end[now]++; 22 } 23 void build() 24 { 25 int head=0,tail=0; 26 for(int i=0;i<26;i++) if(tr[0][i]) q[++tail]=tr[0][i]; 27 while(++head<=tail) 28 { 29 int x=q[head]; 30 for(int i=0;i<26;i++) 31 { 32 if(!tr[x][i]) tr[x][i]=tr[fail[x]][i]; 33 else fail[tr[x][i]]=tr[fail[x]][i],q[++tail]=tr[x][i]; 34 } 35 } 36 } 37 void find() 38 { 39 scanf("%s",ch+1); int x=0,ans=0; 40 for(int i=1;i<=strlen(ch+1);i++) 41 { 42 while(x&&!tr[x][ch[i]-\'a\'])x=fail[x]; x=tr[x][ch[i]-\'a\']; int temp=x; 43 while(temp){ans+=end[temp];temp=fail[temp];} 44 } 45 printf("%d\\n",ans); 46 } 47 int main() 48 { 49 freopen("cin.in","r",stdin); 50 freopen("cout.out","w",stdout); 51 scanf("%d",&n); 52 for(int i=1;i<=n;i++) {scanf("%s",ch+1); insert();} 53 build(); 54 find(); 55 return 0; 56 }
10、后缀数组
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<ctime> 6 #include<cmath> 7 #include<algorithm> 8 using namespace std; 9 #define以上是关于模板集合——持续更新中的主要内容,如果未能解决你的问题,请参考以下文章