>w<ios
Windows對拍:vim
1 @echo off 2 3 set paht=C:\Windows\System32 4 5 :loop 6 7 data.exe 8 ddd.exe 9 pai.exe 10 11 fc ddd.out pai.out 12 13 if not errorlevel 1 goto loop 14 15 pause 16 17 goto loop
gvim配置:數組
set ts=4 set sw=4 set smarttab set number color desert syntax on set cindent set guifont=Consolas:h16 imap ee <Esc>:w<CR>
一行gcd:ide
1 LL gcd(LL x,LL y){ return (y ? gcd(y,x%y) : x);}
線性基(帶求交):oop
1 struct bss{ 2 int b[32]; 3 bss(){ 4 for(int i=0;i<=31;++i) b[i]=0; 5 } 6 bss(int x[]){ 7 for(int i=0;i<=31;++i) b[i]=x[i]; 8 } 9 void ist(int x){ 10 for(int i=31;i>=0;--i)if(x>>i&1){ 11 if(!b[i]){ 12 b[i]=x; 13 return ; 14 } 15 x^=b[i]; 16 } 17 } 18 bool chck(int x){ 19 for(int i=31;i>=0;--i)if(x>>i&1) 20 x^=b[i]; 21 return !x; 22 } 23 }; 24 bss mg(bss x,bss y){ 25 bss bwl=x,nb=x,z; 26 for(int i=0;i<=31;++i)if(y.b[i]){ 27 int tma=0,tmb=y.b[i]; 28 for(int j=i;j>=0;--j)if(tmb>>j&1){ 29 if(bwl.b[j]){ 30 tmb^=bwl.b[j],tma^=nb.b[j]; 31 if(!tmb){ 32 z.b[i]=tma; 33 break; 34 } 35 } 36 else{ 37 bwl.b[j]=tmb; 38 nb.b[j]=tma; 39 break; 40 } 41 } 42 } 43 return z; 44 }
(小根)堆:優化
1 int hp[110000],sz=0; 2 void ist(int z){ 3 int x; hp[x=(++sz)]=z; 4 while(x!=1 && hp[x]<hp[x>>1]) swap(hp[x],hp[x>>1]),x>>=1; 5 } 6 void pp(){ 7 hp[1]=hp[sz--]; 8 int x=1,mnid=1; 9 for(;;){ 10 mnid=x; 11 if((x<<1)<=sz && hp[x<<1]<hp[mnid]) mnid=(x<<1); 12 if((x<<1|1)<=sz && hp[x<<1|1]<hp[mnid]) mnid=(x<<1|1); 13 if(mnid==x) break; 14 swap(hp[mnid],hp[x]); 15 x=mnid; 16 } 17 }
後綴數組(下標從1開始):ui
1 char s[1100000]; int n=0; 2 int rk[1100000],hght[1100000]; 3 int cnt[220],cntrk[1100000]; 4 int rk1[1100000],rk2[1100000]; 5 int sa[1100000],tmpsa[1100000]; 6 void gtsffxrk(){ 7 memset(cnt,0,sizeof(cnt)); 8 for(int i=1;i<=n;++i) ++cnt[(int)s[i]]; 9 for(int i=1;i<=210;++i) cnt[i]+=cnt[i-1]; 10 for(int i=1;i<=n;++i) rk[i]=cnt[(int)s[i]]; 11 for(int l=1;l<n;l<<=1){ 12 for(int i=1;i<=n;++i) rk1[i]=rk[i],rk2[i]=(i+l>n ? 0 : rk[i+l]); 13 fill(cntrk+1,cntrk+1+n,0); 14 //每一步都必須fill,由於cntrk求了前綴和,cntrk--並不會把全部cntrk都減成0 15 for(int i=1;i<=n;++i) ++cntrk[rk2[i]]; 16 for(int i=1;i<=n;++i) cntrk[i]+=cntrk[i-1]; 17 //i從1開始,注意由於空字符的存在因此仍是有0rank的 18 for(int i=n;i>=1;--i) tmpsa[cntrk[rk2[i]]--]=i; 19 fill(cntrk+1,cntrk+1+n,0); 20 for(int i=1;i<=n;++i) ++cntrk[rk1[i]]; 21 for(int i=1;i<=n;++i) cntrk[i]+=cntrk[i-1]; 22 for(int i=n;i>=1;--i) sa[cntrk[rk1[tmpsa[i]]]--]=tmpsa[i]; 23 rk[sa[1]]=1; 24 //若是rank從0開始,對於所有同樣的串如"aaaa"會出問題,把最小的rank和空字符混淆 25 bool flg=true; 26 for(int i=2;i<=n;++i){ 27 rk[sa[i]]=rk[sa[i-1]]; 28 rk[sa[i]]+=(rk1[sa[i]]!=rk1[sa[i-1]] || rk2[sa[i]]!=rk2[sa[i-1]]); 29 if(rk1[sa[i]]==rk1[sa[i]] || rk2[sa[i]]==rk2[sa[i]]) flg=false; 30 //if(rk[sa[i]]==rk[sa[i-1]]) flg=false; 31 } 32 if(flg) break; 33 } 34 } 35 void gthght(){ 36 int l=0; 37 for(int i=1;i<=n;++i)if(rk[i]>1){ 38 int j=sa[rk[i]-1]; 39 while(i+l<=n && j+l<=n && s[i+l]==s[j+l]) ++l; 40 //i+l表示的其實是長度爲i+l-1的串的最後一個字符 41 hght[rk[i]]=l; 42 l-=(l>0); 43 } 44 }
dinic(當前弧優化):spa
1 const LL oo=1000000000000007; 2 struct edg{int y,nxt; LL v;}e[11000]; int lk[110],ltp=1; 3 //注意兩倍邊數組 4 void ist(int x,int y,int z){ 5 e[++ltp]=(edg){y,lk[x],z}; lk[x]=ltp; 6 //注意結構體內變量順序 7 e[++ltp]=(edg){x,lk[y],0}; lk[y]=ltp; 8 //由於要用i^1表示反向邊因此邊的標號從2開始 9 } 10 int n,m; int s,t; 11 int lvl[110]; 12 int q[110],hd=0; 13 int crt[110]; 14 bool gtlvl(){ 15 memset(lvl,0,sizeof(lvl)); 16 lvl[q[hd=1]=s]=1; 17 for(int k=1;k<=hd;++k){ 18 crt[q[k]]=lk[q[k]]; 19 //注意crt要初始化 20 for(int i=lk[q[k]];i;i=e[i].nxt)if(e[i].v && !lvl[e[i].y]){ 21 q[++hd]=e[i].y; 22 lvl[e[i].y]=lvl[q[k]]+1; 23 } 24 } 25 return lvl[t]; 26 } 27 LL mxflw(int x,LL y){ 28 if(x==t) return y; 29 LL bwl=0,flw=0; 30 for(int i=crt[x];i && bwl<y;i=e[i].nxt)if(lvl[e[i].y]==lvl[x]+1 && e[i].v) 31 //注意i=crt[x] 32 if((flw=mxflw(e[i].y,min(y-bwl,e[i].v)))){ 33 //注意y和v,易錯點 34 e[i].v-=flw,e[i^1].v+=flw; 35 bwl+=flw; 36 if(!e[i].v) crt[x]=e[i].nxt; 37 //惟一的改動,很好寫 38 //注意必須某條邊跑滿才能換下一個,不然會負優化 39 } 40 if(!bwl) lvl[x]=0; 41 return bwl; 42 } 43 LL dnc(){ 44 LL bwl=0,flw=0; 45 while(gtlvl())while((flw=mxflw(s,oo))) bwl+=flw; 46 return bwl; 47 }
平衡樹treap(假刪除):3d
1 int c[110000][2],v[110000],u[110000],sz[110000],ntp=0,rt=0; 2 int nb[110000],fth[110000]; 3 void rtt(int x,bool mk){ 4 int l=mk^1,r=mk,y=fth[x],z=fth[fth[x]]; 5 //l和r的選取必須看以左旋仍是右旋爲例 6 if(c[x][r]) fth[c[x][r]]=y; 7 //c[x][r]可能爲空 8 fth[y]=x,fth[x]=z; 9 c[y][l]=c[x][r],c[x][r]=y; 10 //x確定有爸爸,沒有爸爸旋個毛線 11 if(z) c[z][c[z][1]==y]=x; //注意這裏不是l和r 12 //總共涉及到3條邊,因此共有6個賦值 13 sz[x]=sz[y],sz[y]=sz[c[y][0]]+sz[c[y][1]]+nb[y]; 14 if(y==rt) rt=x; 15 //注意rt 16 } 17 void mt(int x){ 18 while(fth[x] && u[x]<u[fth[x]]) rtt(x,c[fth[x]][0]==x); 19 } 20 void ist(int x,int y,int z){ 21 if(!x){ 22 x=++ntp; 23 if(!rt) rt=x; 24 v[x]=z,u[x]=rand(); 25 sz[x]=1,nb[x]=1; 26 fth[x]=y; if(y) c[y][z>v[y]]=x; 27 //x確定要設置爸爸,但爸爸可能爲空,細節要考慮到 28 c[x][0]=0,c[x][1]=0; 29 mt(x); 30 return ; 31 } 32 ++sz[x]; 33 if(z==v[x]) ++nb[x]; 34 else ist(c[x][z>v[x]],x,z); 35 } 36 void dlt(int x,int z){ 37 if(!x) return ; 38 --sz[x]; 39 if(z==v[x]) --nb[x]; 40 else dlt(c[x][z>v[x]],z); 41 return ; 42 } 43 int gtrk(int x,int z){ 44 if(!x) return -1; 45 if(z==v[x]) return sz[c[x][0]]+1; 46 else return gtrk(c[x][z>v[x]],z)+(z>v[x] ? sz[c[x][0]]+nb[x] : 0); 47 } 48 int slct(int x,int z){ 49 if(!x) return -1; 50 if(z<=sz[c[x][0]]) return slct(c[x][0],z); 51 //注意別寫混成gtrk 52 else if(z-sz[c[x][0]]<=nb[x]) return v[x]; 53 else return slct(c[x][1],z-sz[c[x][0]]-nb[x]); 54 } 55 int gtcsctv(int x,int z,bool mk){ 56 int l=mk,r=mk^1; 57 //前驅後繼也是鏡像操做 58 while(v[x]!=z){ 59 if(!c[x][z>v[x]]){ 60 ist(rt,0,z),dlt(rt,z); 61 //注意必定要從rt開始插入和刪除,若是從x開始會有不少問題 62 //好比被旋走,好比插入途徑加的sz沒有刪乾淨 63 x=ntp; 64 } 65 //保證第一遍查找的時候不會找到假節點 66 else x=c[x][z>v[x]]; 67 //注意必定要else,不然新插入的點可能會被maintain跑 68 } 69 if(!c[x][l]){ 70 while(fth[x] && c[fth[x]][r]!=x) x=fth[x]; 71 if(!fth[x]) return -1; 72 x=fth[x]; 73 } 74 else{ 75 //注意這裏是else,若是開始爸爸就不用再找兒子了 76 x=c[x][l]; 77 while(c[x][r]) x=c[x][r]; 78 } 79 if(nb[x]) return v[x]; 80 else return gtcsctv(x,v[x],mk); 81 //若是偷懶不刪除則要注意找到的點是否已經沒有數了 82 //感受這樣容易反覆查找被卡,可是沒有證據 83 }
cdq分治(三維數星星小於等於版):code
1 void cdq(int l,int r,int cl,int cr){ 2 if(l>=r) return ; 3 if(cl==cr){ 4 for(int i=l;i<=r;++i){ 5 int tmp=1; 6 //注意這裏對於全等點的處理 7 while(i+tmp<=r && a[i+tmp].a==a[i].a && a[i+tmp].c==a[i].c) ++tmp; 8 //i+tmp表示的其實是長度爲tmp+1的區間的右端點 9 for(int j=0;j<tmp;++j) a[i+j].ans+=tmp-1+qry(a[i].c); 10 //別忘了qry 11 mdf(a[i].c,tmp); 12 i+=tmp-1; 13 //注意是+tmp-1不是=也不是+tmp 14 } 15 for(int i=l;i<=r;++i) mdf(a[i].c,-1); 16 return ; 17 } 18 int md=(cl+cr)>>1; 19 int cnt1=0,cnt2=0; 20 for(int i=l;i<=r;++i){ 21 if(a[i].b<=md){ 22 mdf(a[i].c,1); 23 ++cnt1; 24 } 25 else{ 26 a[i].ans+=qry(a[i].c); 27 ++cnt2; 28 } 29 } 30 for(int i=l;i<=r;++i)if(a[i].b<=md) mdf(a[i].c,-1); 31 cnt1+=l; cnt2+=cnt1; 32 for(int i=r;i>=l;--i) q[--(a[i].b<=md ? cnt1 : cnt2)]=a[i]; 33 for(int i=l;i<=r;++i) a[i]=q[i]; 34 cdq(l,cnt2-1,cl,md),cdq(cnt2,r,md+1,cr); 35 } 36 bool cmp(nds x,nds y){ return (x.a==y.a ? (x.b==y.b ? x.c<y.c : x.b<y.b) : x.a<y.a);} 37 //這個順序很重要
樹狀數組:
1 inline int lbt(int x){ return x&-x;} 2 //v[x]統計的是[x-lowbit(x)+1,x]的全部數 3 void mdf(int x,int z){ while(x<=m){ v[x]+=z; x+=lbt(x);}} 4 //+lowbit的目的不是把1變成0,而是把0變成1 5 int qry(int x){ 6 int bwl=0; 7 while(x){ bwl+=v[x]; x-=lbt(x);} 8 return bwl; 9 }
tarjan求割點(無向圖):
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 int rd(){int z=0,mk=1; char ch=getchar(); 8 while(ch<'0'||ch>'9'){if(ch=='-')mk=-1; ch=getchar();} 9 while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0'; ch=getchar();} 10 return z*mk; 11 } 12 struct edg{int y,nxt;}e[210000]; int lk[21000],ltp=0; 13 void ist(int x,int y){ 14 e[++ltp]=(edg){y,lk[x]}; lk[x]=ltp; 15 e[++ltp]=(edg){x,lk[y]}; lk[y]=ltp; 16 } 17 int n,m; 18 int dfn[21000],low[21000],dft=0; 19 int aq[21000],atp=0; 20 void tj(int x,int y){ 21 dfn[x]=++dft; low[x]=dfn[x]; 22 bool flg1=false,flg2=false; 23 for(int i=lk[x];i;i=e[i].nxt)if(e[i].y!=y){ 24 if(!dfn[e[i].y]){ 25 tj(e[i].y,x); 26 if(!y && flg1) flg2=true; 27 //注意順序!放到後邊就錯了 28 if(low[e[i].y]>=dfn[x]) flg1=true; 29 low[x]=min(low[x],low[e[i].y]); 30 } 31 else low[x]=min(low[x],dfn[e[i].y]); 32 //注意這裏是dfn 33 } 34 if(y && flg1) aq[++atp]=x; 35 if(!y && flg2) aq[++atp]=x; 36 } 37 void prvs(){ 38 for(int i=1;i<=n;++i) dfn[i]=0,low[i]=0; 39 dft=0; 40 atp=0; 41 } 42 int main(){ 43 //freopen("ddd.in","r",stdin); 44 cin>>n>>m; prvs(); 45 int l,r; 46 while(m --> 0){ l=rd(),r=rd(); ist(l,r);} 47 for(int i=1;i<=n;++i)if(!dfn[i]) tj(i,0); 48 sort(aq+1,aq+atp+1); 49 printf("%d\n",atp); 50 for(int i=1;i<=atp;++i) printf("%d ",aq[i]); 51 printf("\n"); 52 return 0; 53 }
手寫堆排序:
1 nds a[110000]; 2 bool cmp(nds &x,nds &y){ return x.c<y.c;} 3 void st(){ 4 for(int i=1;i<=m;++i) 5 for(int j=i;j>1 && b[j].c<b[j>>1].c;j>>=1) swap(b[j],b[j>>1]); 6 int sz=m; 7 for(int i=1;i<=m;++i){ 8 a[i]=b[1]; 9 swap(b[1],b[sz--]); 10 for(int j=1;j<=sz;){ 11 int k=j; 12 if((j<<1)<=sz && b[j<<1].c<b[k].c) k=(j<<1); 13 if((j<<1|1)<=sz && b[j<<1|1].c<b[k].c) k=(j<<1|1); 14 if(k==j) break; 15 swap(b[j],b[k]); 16 j=k; 17 } 18 } 19 for(int i=1;i<=m;++i) b[i]=a[i]; 20 }
>w<