• 省选前模板整理


    [TOC]

    假装有目录(以前就是有的)

    woc明天就走了怎么这么多没写


    之前写的忘得差不多了,再写遍(省选部分模板连同一些比较水的。。)。

    就按分类顺序排了。另外还是Markdown好用,但可惜不能代码折叠。光改字体就好麻烦啊。。


    计算几何。。

    DP

    斜率优化

    四边形不等式优化


    分治

    CDQ分治✔

     三维偏序:http://www.cnblogs.com/SovietPower/p/8574905.html

     1 /*
     2 5904kb    840ms
     3 是对x,y,z都相同的元素去重,不是对z。。sb了。
     4 去重后的贡献是q[p].cnt!
     5 */
     6 #include <cstdio>
     7 #include <cctype>
     8 #include <algorithm>
     9 #define gc() getchar()
    10 #define lb(x) (x)&-(x)
    11 const int N=1e5+5,MAXN=2e5+5;
    12 
    13 int n,Ans[N];
    14 int read();
    15 struct Node
    16 {
    17     int x,y,z,cnt,ans;
    18     void Init(){
    19         x=read(),y=read(),z=read(),cnt=1;
    20     }
    21     bool operator <(const Node &a)const{
    22         return x==a.x?(y==a.y?z<a.z:y<a.y):x<a.x;
    23     }
    24 }q[N],tmp[N];
    25 
    26 inline int read()
    27 {
    28     int now=0;register char c=gc();
    29     for(;!isdigit(c);c=gc());
    30     for(;isdigit(c);now=now*10+c-'0',c=gc());
    31     return now;
    32 }
    33 namespace BIT
    34 {
    35     int n,val[MAXN];
    36     inline void Add(int p,int v){
    37         while(p<=n) val[p]+=v,p+=lb(p);
    38     }
    39     inline int Query(int p){
    40         int res=0;
    41         while(p) res+=val[p],p-=lb(p);
    42         return res;
    43     }
    44     inline void Clear(int p){
    45         while(p<=n)
    46             if(val[p]) val[p]=0,p+=lb(p);
    47             else break;
    48     }
    49 }
    50 void CDQ(int l,int r)
    51 {
    52     if(l<r){
    53         int m=l+r>>1; CDQ(l,m), CDQ(m+1,r);
    54         int p1=l,p2=m+1,t=0;
    55         while(p1<=m&&p2<=r)
    56         {
    57             if(q[p1].y<=q[p2].y) BIT::Add(q[p1].z,q[p1].cnt), tmp[t++]=q[p1++];//只是排y,别去管什么z。。
    58             else q[p2].ans+=BIT::Query(q[p2].z), tmp[t++]=q[p2++];
    59         }
    60         if(p1<=m){
    61             for(int i=l; i<p1; ++i) BIT::Clear(q[i].z);
    62             while(p1<=m) tmp[t++]=q[p1++];
    63         }
    64         else if(p2<=r){
    65             while(p2<=r) q[p2].ans+=BIT::Query(q[p2].z), tmp[t++]=q[p2++];
    66             for(int i=l; i<=m; ++i) BIT::Clear(q[i].z);
    67         }
    68         for(int i=0; i<t; ++i) q[l+i]=tmp[i];
    69     }
    70 }
    71 
    72 int main()
    73 {
    74     n=read(),BIT::n=read();
    75     for(int i=1; i<=n; ++i) q[i].Init();
    76     std::sort(q+1,q+1+n);
    77     int cnt=1;
    78     for(int i=2; i<=n; ++i)
    79         if(q[i].z!=q[i-1].z||q[i].y!=q[i-1].y||q[i].x!=q[i-1].x) q[++cnt]=q[i];
    80         else ++q[cnt].cnt;
    81     CDQ(1,cnt);
    82     for(int i=1; i<=cnt; ++i) Ans[q[i].ans+q[i].cnt-1]+=q[i].cnt;
    83     for(int i=0; i<n; ++i) printf("%d
    ",Ans[i]);
    84 
    85     return 0;
    86 }
    CDQ分治 三维偏序

    点分治✔

    http://www.cnblogs.com/SovietPower/p/8589571.html

     1 #include <cstdio>
     2 #include <cctype>
     3 #include <algorithm>
     4 #define gc() getchar()
     5 const int N=1e4+5,S=1e7+5;
     6 
     7 int n,m,Enum,root,Min,sz[N],H[N],to[N<<1],nxt[N<<1],val[N<<1],D[N],que[N],Q[105],Ans[105];
     8 bool vis[N],exist[S];//bitset随便用会更慢。。
     9 
    10 inline int read()
    11 {
    12     int now=0;register char c=gc();
    13     for(;!isdigit(c);c=gc());
    14     for(;isdigit(c);now=now*10+c-'0',c=gc());
    15     return now;
    16 }
    17 inline void AddEdge(int u,int v,int w)
    18 {
    19     to[++Enum]=v, nxt[Enum]=H[u], val[Enum]=w, H[u]=Enum;
    20     to[++Enum]=u, nxt[Enum]=H[v], val[Enum]=w, H[v]=Enum;
    21 }
    22 void Get_root(int x,int f,int tot)
    23 {
    24     int mx=0; sz[x]=1;
    25     for(int v,i=H[x]; i; i=nxt[i])
    26         if(!vis[v=to[i]] && v!=f)
    27         {
    28             Get_root(v,x,tot), sz[x]+=sz[v];
    29             if(sz[v]>mx) mx=sz[v];
    30         }
    31     mx=std::max(mx,tot-sz[x]);
    32     if(mx<Min) Min=mx,root=x;
    33 }
    34 void DFS(int x,int f,int d)
    35 {
    36     D[++D[0]]=d;
    37     for(int i=H[x]; i; i=nxt[i])
    38         if(!vis[to[i]] && to[i]!=f) DFS(to[i],x,d+val[i]);
    39 }
    40 void Calc(int x,int val)
    41 {
    42     D[0]=0, DFS(x,x,val);
    43     for(int i=1; i<=D[0]; ++i)
    44         for(int j=1; j<=m; ++j)
    45             if(Q[j]>=D[i]) Ans[j]|=exist[Q[j]-D[i]];
    46     for(int i=1; i<=D[0]; ++i)
    47         exist[D[i]]=1,que[++que[0]]=D[i];
    48 }
    49 void Solve(int x)
    50 {
    51     vis[x]=1, que[0]=0, exist[0]=1/*!*/;
    52     for(int i=H[x]; i; i=nxt[i])
    53         if(!vis[to[i]]) Calc(to[i],val[i]);
    54     for(int i=1; i<=que[0]; ++i) exist[que[i]]=0;
    55     for(int i=H[x]; i; i=nxt[i])
    56         if(!vis[to[i]])
    57             Min=N, Get_root(to[i],x,sz[to[i]]), Solve(root);
    58 }
    59 
    60 int main()
    61 {
    62     n=read(),m=read();
    63     for(int u,v,i=1; i<n; ++i) u=read(),v=read(),AddEdge(u,v,read());
    64     for(int i=1; i<=m; ++i) Q[i]=read();
    65     Min=N, Get_root(1,1,n), Solve(root);
    66     for(int i=1; i<=m; ++i) puts(Ans[i]?"AYE":"NAY");
    67 
    68     return 0;
    69 }
    点分治

    数据结构

    线段树、树状数组、Trie树略

    分块

    树分块/块状树

    Splay✔

    http://www.cnblogs.com/SovietPower/p/8435011.html

      1 #include <cstdio>
      2 #include <cctype>
      3 #include <algorithm>
      4 //#define gc() getchar()
      5 #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
      6 #define MAXIN 500000
      7 const int N=2e5+5;
      8 
      9 char IN[MAXIN],*SS=IN,*TT=IN;
     10 inline int read()
     11 {
     12     int now=0,f=1;register char c=gc();
     13     for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
     14     for(;isdigit(c);now=now*10+c-'0',c=gc());
     15     return now*f;
     16 }
     17 namespace Splay
     18 {
     19     #define lson son[x][0]
     20     #define rson son[x][1]
     21 
     22     int root,size,fa[N],son[N][2],sz[N],t[N],cnt[N];
     23     inline void Update(int x){
     24         sz[x]=sz[lson]+sz[rson]+cnt[x];
     25     }
     26     void Rotate(int x,int &k)
     27     {
     28         int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
     29         if(k==a) k=x;
     30         else son[b][son[b][1]==a]=x;
     31         fa[a]=x, fa[x]=b, fa[son[x][r]]=a,
     32         son[a][l]=son[x][r], son[x][r]=a;
     33         Update(a);// Update(x);
     34     }
     35     void Splay(int x,int &k)
     36     {
     37         while(x!=k)
     38         {
     39             int a=fa[x],b=fa[a];
     40             if(a!=k) (son[a][1]==x^son[b][1]==a)?Rotate(x,k):Rotate(a,k);
     41             Rotate(x,k);
     42         }
     43         Update(x);
     44     }
     45     void Insert(int v,int k)
     46     {
     47         int f=0;
     48         while(t[k]!=v&&k) f=k,k=son[k][v>t[k]];
     49         if(k) ++cnt[k];
     50         else{
     51             k=++size, sz[k]=cnt[k]=1, t[k]=v, fa[k]=f;
     52             if(f) son[f][v>t[f]]=k;
     53         }
     54         Splay(k,root);
     55     }
     56     void Rank(int v,int k)
     57     {
     58 //        if(!k) return;
     59         while(t[k]!=v && son[k][v>t[k]]) k=son[k][v>t[k]];
     60         Splay(k,root);
     61     }
     62     void Delete(int v,int k)
     63     {
     64         Rank(v,root);
     65         if(cnt[root]>1) --cnt[root],--sz[root];
     66         else if(son[root][0]&&son[root][1])
     67         {
     68             int ls=son[root][0],k=son[root][1];
     69             fa[root=k]=0;
     70             while(son[k][0]) k=son[k][0];
     71             fa[ls]=k, son[k][0]=ls;// sz[k]+=sz[ls];
     72             Splay(k,root);
     73         }
     74         else root=son[root][0]^son[root][1],fa[root]=0;
     75     }
     76     int Get_Rank(int k,int x)
     77     {
     78         while(1)
     79         {
     80             if(sz[lson]<k && sz[lson]+cnt[x]>=k) return x;
     81             if(sz[lson]<k) k-=sz[lson]+cnt[x],x=rson;
     82             else x=lson;
     83         }
     84     }
     85     int Find(int v,int w)
     86     {
     87         Rank(v,root);
     88         if((t[root]>v&&!w)||(t[root]<v&&w)) return root;//!
     89         int x=son[root][w^1];
     90         while(son[x][w]) x=son[x][w];
     91         return x;
     92     }
     93 }
     94 using namespace Splay;
     95 
     96 int main()
     97 {
     98     int n=read(),opt;
     99     while(n--)
    100         switch(opt=read())
    101         {
    102             case 1: Insert(read(),root); break;
    103             case 2: Delete(read(),root); break;
    104             case 3: Rank(read(),root),printf("%d
    ",sz[son[root][0]]+1); break;
    105             case 4: printf("%d
    ",t[Get_Rank(read(),root)]); break;
    106             case 5: printf("%d
    ",t[Find(read(),1)]); break;
    107             case 6: printf("%d
    ",t[Find(read(),0)]); break;
    108         }
    109     return 0;
    110 }
    Splay

    LCT✔

    模板:http://www.cnblogs.com/SovietPower/p/8615938.html 

     1 #include <cstdio>
     2 #include <cctype>
     3 #include <algorithm>
     4 #define gc() getchar()
     5 const int N=3e5+5;
     6 
     7 inline int read()
     8 {
     9     int now=0;register char c=gc();
    10     for(;!isdigit(c);c=gc());
    11     for(;isdigit(c);now=now*10+c-'0',c=gc());
    12     return now;
    13 }
    14 namespace LCT
    15 {
    16     #define lson son[x][0]
    17     #define rson son[x][1]
    18 
    19     int fa[N],son[N][2],sum[N],val[N],sk[N];
    20     bool rev[N];
    21     inline void Update(int x){
    22         sum[x]=sum[lson]^sum[rson]^val[x];
    23     }
    24     inline bool n_root(int x){
    25         return son[fa[x]][0]==x||son[fa[x]][1]==x;
    26     }
    27     inline void Rev(int x){
    28         std::swap(lson,rson), rev[x]^=1;
    29     }
    30     inline void PushDown(int x){
    31         if(rev[x]) Rev(lson),Rev(rson),rev[x]=0;
    32     }
    33     void Rotate(int x)
    34     {
    35         int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
    36         if(n_root(a)) son[b][son[b][1]==a]=x;
    37         if(son[x][r]) fa[son[x][r]]=a;
    38         fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
    39         Update(a);
    40     }
    41     void Splay(int x)
    42     {
    43         int t=1,a=x; sk[1]=x;
    44         while(n_root(a)) sk[++t]=a=fa[a];
    45         while(t) PushDown(sk[t--]);
    46         while(n_root(x))
    47         {
    48             if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
    49             Rotate(x);
    50         }
    51         Update(x);
    52     }
    53     void Access(int x){
    54         for(int pre=0; x; x=fa[pre=x])
    55             Splay(x), rson=pre, Update(x);
    56     }
    57     void Make_root(int x){
    58         Access(x), Splay(x), Rev(x);
    59     }
    60     void Split(int x,int y){
    61         Make_root(x), Access(y), Splay(y);
    62     }
    63     int Find_root(int x)
    64     {
    65         Access(x), Splay(x);
    66         while(lson) x=lson;
    67         return x;
    68     }
    69     void Link(int x,int y)
    70     {
    71         Make_root(x);
    72         if(Find_root(y)!=x) fa[x]=y;
    73     }
    74     void Cut(int x,int y)
    75     {
    76         Make_root(x);
    77         if(Find_root(y)==x&&fa[x]==y&&!rson)
    78             fa[x]=son[y][0]=0, Update(y);
    79     }
    80 }
    81 using namespace LCT;
    82 
    83 int main()
    84 {
    85     int n=read(),m=read(),opt,x,y;
    86     for(int i=1; i<=n; ++i) val[i]=read();
    87     while(m--)
    88         switch(opt=read(),x=read(),y=read(),opt)
    89         {
    90             case 0: Split(x,y),printf("%d
    ",sum[y]); break;
    91             case 1: Link(x,y); break;
    92             case 2: Cut(x,y); break;
    93             case 3: Splay(x), val[x]=y; break;
    94         }
    95     return 0;
    96 }
    LCT

    可是很多东西都不熟啊QAQ:http://www.cnblogs.com/SovietPower/category/1182810.html

    fhq Treap✔

    http://www.cnblogs.com/SovietPower/p/8431909.html

     1 #include <cstdio>
     2 #include <cctype>
     3 #include <algorithm>
     4 #define gc() getchar()
     5 const int N=1e5+5;
     6 
     7 inline int read()
     8 {
     9     int now=0,f=1;register char c=gc();
    10     for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    11     for(;isdigit(c);now=now*10+c-'0',c=gc());
    12     return now*f;
    13 }
    14 namespace fhq_Treap
    15 {
    16     #define lson son[rt][0]
    17     #define rson son[rt][1]
    18 
    19     int tot,fa[N],son[N][2],sz[N],val[N],fix[N];
    20     inline int New_Node(int v){
    21         fix[++tot]=rand(), val[tot]=v, sz[tot]=1;
    22         return tot;
    23     }
    24     inline void Update(int rt){
    25         sz[rt]=sz[lson]+sz[rson]+1;
    26     }
    27     void Split(int rt,int v,int &x,int &y)
    28     {
    29         if(!rt) x=y=0;
    30         else{
    31             if(val[rt]<=v) x=rt,Split(rson,v,rson,y);//val[rt] not val[x]..
    32             else y=rt,Split(lson,v,x,lson);
    33             Update(rt);
    34         }
    35     }
    36     int Merge(int x,int y)
    37     {
    38         if(!x||!y) return x^y;
    39         if(fix[x]<fix[y]){
    40             son[x][1]=Merge(son[x][1],y), Update(x);
    41             return x;
    42         }
    43         else{
    44             son[y][0]=Merge(x,son[y][0]), Update(y);
    45             return y;
    46         }
    47     }
    48     int Rank(int k,int rt)
    49     {
    50         while(1)
    51         {
    52             if(sz[lson]+1==k) return rt;
    53             if(sz[lson]<k) k-=sz[lson]+1,rt=rson;
    54             else rt=lson;
    55         }
    56     }
    57     int Find(int rt,int w)
    58     {
    59         while(son[rt][w]) rt=son[rt][w];
    60         return rt;
    61     }
    62 }
    63 using namespace fhq_Treap;
    64 
    65 int main()
    66 {
    67     int n=read(),opt,v,x,y,z,root=0;
    68     while(n--)
    69         switch(opt=read(),v=read(),opt)
    70         {
    71             case 1: Split(root,v,x,y),x=Merge(x,New_Node(v)),root=Merge(x,y);
    72                     break;
    73             case 2: Split(root,v,x,z),Split(x,v-1,x,y),y=Merge(son[y][0],son[y][1]),root=Merge(Merge(x,y),z);
    74                     break;
    75             case 3: Split(root,v-1,x,y),printf("%d
    ",sz[x]+1),root=Merge(x,y);
    76                     break;
    77             case 4: printf("%d
    ",val[Rank(v,root)]);
    78                     break;
    79             case 5: Split(root,v-1,x,y),printf("%d
    ",val[Find(x,1)]),root=Merge(x,y);
    80                     break;
    81             case 6: Split(root,v,x,y),printf("%d
    ",val[Find(y,0)]),root=Merge(x,y);
    82                     break;
    83         }
    84     return 0;
    85 }
    fhq Treap

    树链剖分

    树套树 二维线段树

    主席树 树上第k大(小)✔

    区间第k大略

    http://www.cnblogs.com/SovietPower/p/8443615.html

     1 //10^5还是需要18*10^5的空间!
     2 #include <cstdio>
     3 #include <cctype>
     4 #include <algorithm>
     5 #define gc() getchar()
     6 const int N=1e5+5;
     7 
     8 int n,Q,cnt,ref[N],A[N],H[N],Enum,nxt[N<<1],to[N<<1],root[N],top[N],dep[N],sz[N],son[N],fa[N];
     9 
    10 inline int read()
    11 {
    12     int now=0,f=1;register char c=gc();
    13     for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    14     for(;isdigit(c);now=now*10+c-'0',c=gc());
    15     return now*f;
    16 }
    17 inline void AddEdge(int u,int v)
    18 {
    19     to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    20     to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
    21 }
    22 namespace T//Seg_Tree
    23 {
    24     #define lson son[x][0]
    25     #define rson son[x][1]
    26 
    27     int tot,sum[N*17],son[N*17][2];
    28     void Insert(int x,int &y,int l,int r,int p)
    29     {
    30         sum[y=++tot]=sum[x]+1;
    31         if(l<r){
    32             int m=l+r>>1;
    33             if(p<=m) son[y][1]=rson,Insert(lson,son[y][0],l,m,p);
    34             else son[y][0]=lson,Insert(rson,son[y][1],m+1,r,p);
    35         }
    36     }
    37     int Query(int x,int y,int lca,int falca,int l,int r,int k)
    38     {
    39         if(l==r) return l;
    40         int delta=sum[lson]+sum[son[y][0]]-sum[son[lca][0]]-sum[son[falca][0]];
    41         if(delta<k) return Query(rson,son[y][1],son[lca][1],son[falca][1],(l+r>>1)+1,r,k-delta);
    42         return Query(lson,son[y][0],son[lca][0],son[falca][0],l,l+r>>1,k);
    43     }
    44 }
    45 
    46 int Find(int x)
    47 {
    48     int l=1,r=cnt,mid;
    49     while(l<r)
    50         if(ref[mid=l+r>>1]<x) l=mid+1;
    51         else r=mid;
    52     return l;
    53 }
    54 void DFS1(int x)
    55 {
    56     int mx=0; sz[x]=1;
    57     T::Insert(root[fa[x]],root[x],1,cnt,A[x]);
    58     for(int v,i=H[x]; i; i=nxt[i])
    59         if((v=to[i])!=fa[x])
    60         {
    61             fa[v]=x, dep[v]=dep[x]+1, DFS1(v), sz[x]+=sz[v];
    62             if(sz[v]>mx) mx=sz[v],son[x]=v;
    63         }
    64 }
    65 void DFS2(int x,int tp)
    66 {
    67     top[x]=tp;
    68     if(son[x]){
    69         DFS2(son[x],tp);
    70         for(int i=H[x]; i; i=nxt[i])
    71             if(to[i]!=fa[x] && to[i]!=son[x]) DFS2(to[i],to[i]);
    72     }
    73 }
    74 int LCA(int u,int v)
    75 {
    76     while(top[u]!=top[v])
    77     {
    78         if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
    79         u=fa[top[u]];
    80     }
    81     return dep[u]>dep[v]?v:u;
    82 }
    83 
    84 int main()
    85 {
    86     n=read(),Q=read();
    87     for(int i=1; i<=n; ++i) ref[i]=A[i]=read();
    88     for(int u,v,i=1; i<n; ++i) u=read(),v=read(),AddEdge(u,v);
    89     std::sort(ref+1,ref+1+n), cnt=1;
    90     for(int i=2; i<=n; ++i) if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i];
    91     for(int i=1; i<=n; ++i) A[i]=Find(A[i]);
    92     DFS1(1), DFS2(1,1);
    93     int res=0,u,v,w,k;
    94     while(Q--)
    95         u=read()^res,v=read(),k=read(),w=LCA(u,v),
    96         printf("%d
    ",res=ref[T::Query(root[u],root[v],root[w],root[fa[w]],1,cnt,k)]);
    97 
    98     return 0;
    99 }
    主席树 静态树上第k小

    可并堆 左偏树✔

    http://www.cnblogs.com/SovietPower/p/8435041.html

     1 #include <cstdio>
     2 #include <cctype>
     3 #include <algorithm>
     4 //#define gc() getchar()
     5 #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
     6 #define MAXIN 50000//这个到底需要多大啊QAQ 
     7 const int N=1e5+5,DEL=-1<<30;
     8 
     9 char IN[MAXIN],*SS=IN,*TT=IN;
    10 namespace Leftist_Tree
    11 {
    12     #define lson son[x][0]
    13     #define rson son[x][1]
    14 
    15     int fa[N],son[N][2],dis[N],val[N];
    16     int Merge(int x,int y)
    17     {
    18         if(!x||!y) return x^y;
    19         if(val[x]>val[y]||(val[x]==val[y]&&x>y)) std::swap(x,y);
    20         rson=Merge(rson,y), fa[rson]=x;
    21         if(dis[lson]<dis[rson]) std::swap(lson,rson);
    22         dis[x]=dis[rson]+1;
    23         return x;
    24     }
    25     inline int Top(int x){
    26         while(fa[x]) x=fa[x];
    27         return x;
    28     }
    29 }
    30 using namespace Leftist_Tree;
    31 
    32 inline int read()
    33 {
    34     int now=0,f=1;register char c=gc();
    35     for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
    36     for(;isdigit(c);now=now*10+c-'0',c=gc());
    37     return now*f;
    38 }
    39 
    40 int main()
    41 {
    42     dis[0]=-1;
    43     int n=read(),Q=read(),opt,x,y;
    44     for(int i=1; i<=n; ++i) val[i]=read();
    45     while(Q--)
    46     {
    47         opt=read(),x=read();
    48         if(opt==1)
    49         {
    50             y=read();
    51             if(val[x]==DEL||val[y]==DEL||x==y) continue;
    52             if((x=Top(x))!=(y=Top(y))) Merge(x,y);
    53         }
    54         else if(val[x]==DEL) puts("-1");
    55         else
    56         {
    57             printf("%d
    ",val[x=Top(x)]),val[x]=DEL;
    58             fa[lson]=fa[rson]=0, Merge(lson,rson);//记得清空fa[]!
    59         }
    60     }
    61     return 0;
    62 }
    Leftist Tree

    数学,数论

    CRT

    扩展CRT

    Lucas

    扩展Lucas

    线性求逆元✔

     这么水的东西https://www.luogu.org/problemnew/show/P3811

     1 #include <cstdio>
     2 const int N=3e6+6;
     3 
     4 int n,p,inv[N];
     5 
     6 int main()
     7 {
     8     scanf("%d%d",&n,&p);
     9     inv[1]=1, puts("1");
    10     for(int i=2; i<=n; ++i)
    11         printf("%d
    ",inv[i]=1ll*(p-p/i)*inv[p%i]%p);
    12 
    13     return 0;
    14 }
    线性求逆元

    Miller Rabin

    Pollard Rho

    上面这俩。。

    Catalan数

    博弈论复习

    高斯消元

    莫比乌斯反演✔

     做了。


    图论

    2-SAT

    Matrix Tree✔

    http://www.cnblogs.com/SovietPower/p/8463968.html

    就是那样,只会写模板,不再写了。。

    二分图匹配 匈牙利

    欧拉路

    哈密顿路

    次小生成树

    这个不写了。。倍增十分麻烦,到时候写LCT水过去吧。。

    堆优化Dijkstra✔

    我。。还是再写遍这个吧

    https://www.luogu.org/problemnew/show/P3371

     1 //memset(0x7f)后的值并不是0x7fffffff(略小)!woc才知道。
     2 #include <queue>
     3 #include <cstdio>
     4 #include <cctype>
     5 #include <cstring>
     6 #include <algorithm>
     7 #define gc() getchar()
     8 #define pr std::pair<int,int>
     9 #define mp std::make_pair
    10 const int N=1e4+5,M=5e5+5,INF=0x3f3f3f3f;
    11 
    12 int n,m,S,Enum,H[N],nxt[M],to[M],val[M],dis[N];
    13 std::priority_queue<pr> q;
    14 bool vis[N];
    15 
    16 inline int read()
    17 {
    18     int now=0;register char c=gc();
    19     for(;!isdigit(c);c=gc());
    20     for(;isdigit(c);now=now*10+c-'0',c=gc());
    21     return now;
    22 }
    23 inline void AddEdge(int u,int v,int w){
    24     to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, val[Enum]=w;
    25 }
    26 void Dijkstra()
    27 {
    28     memset(dis,0x3f,sizeof dis);
    29     dis[S]=0, q.push(mp(0,S));
    30     while(!q.empty())
    31     {
    32         int x=q.top().second;q.pop();
    33         if(vis[x]) continue;
    34         vis[x]=1;
    35         for(int v,i=H[x]; i; i=nxt[i])
    36             if(dis[v=to[i]]>dis[x]+val[i])
    37             {
    38                 dis[v]=dis[x]+val[i];
    39                 if(!vis[v]) q.push(mp(-dis[v],v));
    40             }
    41     }
    42 }
    43 
    44 int main()
    45 {
    46     n=read(),m=read(),S=read();
    47     for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),AddEdge(u,v,read());
    48     Dijkstra();
    49     for(int i=1; i<=n; ++i) printf("%d ",dis[i]==INF?0x7fffffff:dis[i]);
    50     return 0;
    51 }
    Dijkstra+heap

    网络流

    Dinic、ISAP、SPFA费用流略。

    无源汇上下界网络流

    有源汇上下界网络流

    有源汇上下界最小流


    字符串

    KMP✔

    https://www.luogu.org/problemnew/show/P3375

     1 #include <cstdio>
     2 #include <cstring>
     3 const int N=1e6+5;
     4 
     5 int len,fail[N];
     6 char p[N],s[N];
     7 
     8 void Get_fail()
     9 {
    10     fail[0]=fail[1]=0;
    11     for(int i=1,j; i<len; ++i)
    12     {
    13         j=fail[i];
    14         while(s[i]!=s[j]&&j) j=fail[j];
    15         fail[i+1]=s[i]==s[j]?j+1:0;
    16     }
    17 }
    18 void KMP()
    19 {
    20     for(int i=0,j=0,l=strlen(p); i<l; ++i)
    21     {
    22         while(p[i]!=s[j]&&j) j=fail[j];
    23         if(p[i]==s[j]) ++j;
    24         if(j==len) printf("%d
    ",i-j+2);
    25     }
    26     for(int i=1; i<=len; ++i) printf("%d ",fail[i]);
    27 }
    28 
    29 int main()
    30 {
    31     scanf("%s%s",p,s), len=strlen(s), Get_fail(), KMP();
    32     return 0;
    33 }
    KMP

    Manacher✔

    http://www.cnblogs.com/SovietPower/p/8677979.html

     1 /*
     2 记录当前ex[]最大的回文中心id和最远延伸范围mx!
     3 关于串的构造: 
     4 应该是 @ #A#B#C#B#A# $,而不是 @ A#B#C#B#A $ 
     5 比如 @a#b#b#c$,答案应是max{ex[i]}-1,而第二种很多情况下答案是max{ex[i]}.
     6 最优解不改串分奇偶讨论感觉sxbk。。
     7 */
     8 #include <cstdio>
     9 #include <cstring>
    10 #include <algorithm>
    11 const int N=22000010;
    12 
    13 int n,ex[N];
    14 char tmp[N>>1],s[N];
    15 
    16 void Init()
    17 {
    18     n=strlen(tmp), s[0]='@';
    19     for(int i=0; i<n; ++i)
    20         s[i<<1|1]='#', s[(i<<1)+2]=tmp[i];
    21     s[n=2*n+2]='$', s[n-1]='#';
    22 }
    23 void Manacher()
    24 {
    25     int res=0,mx=0,id;
    26     for(int i=1; i<n; ++i)
    27     {
    28         if(i<mx) ex[i]=std::min(ex[id*2-i],mx-i);
    29         else ex[i]=1;
    30         while(s[i+ex[i]]==s[i-ex[i]]) ++ex[i];
    31 //        if(ex[i]>res) res=ex[i];//不在这更新也对,懒得想了。。
    32         if(i+ex[i]>mx) id=i,mx=i+ex[i],res=std::max(res,ex[i]);
    33     }
    34     printf("%d",res-1);
    35 }
    36 
    37 int main()
    38 {
    39     scanf("%s",tmp), Init(), Manacher();
    40     return 0;
    41 }
    Manacher

    后缀数组✔

    http://www.cnblogs.com/SovietPower/p/8567563.html

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 const int N=1e6+5;
     5 
     6 int n,tm[N],sa[N],rk[N],sa2[N],ht[N];
     7 char s[N];
     8 
     9 void Get_SA()
    10 {
    11     int *x=rk,*y=sa2,m=28;
    12     for(int i=0; i<=m; ++i) tm[i]=0;
    13     for(int i=1; i<=n; ++i) ++tm[x[i]=s[i]-'a'+1];
    14     for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
    15     for(int i=n; i; --i) sa[tm[x[i]]--]=i;
    16     for(int k=1,p=0; k<n; k<<=1,m=p,p=0)
    17     {
    18         for(int i=n-k+1; i<=n; ++i) y[++p]=i;
    19         for(int i=1; i<=n; ++i) if(sa[i]>k) y[++p]=sa[i]-k;
    20 
    21         for(int i=0; i<=m; ++i) tm[i]=0;
    22         for(int i=1; i<=n; ++i) ++tm[x[i]];
    23         for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
    24         for(int i=n; i; --i) sa[tm[x[y[i]]]--]=y[i];
    25 
    26         std::swap(x,y), p=x[sa[1]]=1;
    27         for(int i=2; i<=n; ++i)
    28             x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
    29         if(p>=n) break;
    30     }
    31     for(int i=1; i<=n; ++i) rk[sa[i]]=i;
    32     ht[1]=0;
    33     for(int k=0,p,i=1; i<=n; ++i)
    34     {
    35         if(rk[i]==1) continue;
    36         if(k) --k;
    37         p=sa[rk[i]-1];//ht[i]>=ht[i-1]-1
    38         while(i+k<=n&&p+k<=n&&s[i+k]==s[p+k]) ++k;
    39         ht[rk[i]]=k;
    40     }
    41 }
    42 
    43 int main()
    44 {
    45     scanf("%s",s+1), n=strlen(s+1), Get_SA();
    46     for(int i=1; i<=n; ++i) printf("%d ",sa[i]);putchar('
    ');
    47     for(int i=2; i<=n; ++i) printf("%d ",ht[i]);
    48 
    49     return 0;
    50 }
    后缀数组 倍增

    AC自动机✔

    http://www.cnblogs.com/SovietPower/p/8530327.html

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 const int N=1e6+5;
     5 
     6 char s[N];
     7 struct AC_Automaton
     8 {
     9     int tot,fail[N],son[N][26],las[N],val[N],q[N];
    10     void Insert(char *s)
    11     {
    12         int l=strlen(s),x=0;
    13         for(int id,i=0; i<l; ++i)
    14         {
    15             id=s[i]-'a';
    16             if(!son[x][id]) son[x][id]=++tot;
    17             x=son[x][id];
    18         }
    19         ++val[x];
    20     }
    21     void Build()
    22     {
    23         int h=0,t=0;
    24         for(int i=0; i<26; ++i)
    25             if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i];
    26         while(h<t)
    27         {
    28             int x=q[h++];
    29             for(int v,i=0; i<26; ++i)
    30                 if(son[x][i])
    31                     fail[v=son[x][i]]=son[fail[x]][i],q[t++]=v,las[v]=val[fail[v]]?fail[v]:las[fail[v]];
    32                 else son[x][i]=son[fail[x]][i];//直接设son[]。
    33         }
    34     }
    35     void Query(char *s)
    36     {
    37         int l=strlen(s),res=0,x=0;
    38         for(int i=0; i<l; ++i)
    39         {
    40             x=son[x][s[i]-'a'];//先走一步 
    41             for(int j=x; j&&~val[j]; j=las[j])
    42                 res+=val[j], val[j]=-1;//不能重复走。
    43         }
    44         printf("%d",res);
    45     }
    46 }ac;
    47 
    48 int main()
    49 {
    50     int n; scanf("%d",&n);
    51     while(n--) scanf("%s",s),ac.Insert(s);
    52     ac.Build(), scanf("%s",s), ac.Query(s);
    53 
    54     return 0;
    55 }
    AC Automaton
     1 #include <cstdio>
     2 #include <cctype>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define gc() getchar()
     6 const int N=152*72,S=26;
     7 
     8 int n;
     9 char s[152][72],p[1000005];
    10 
    11 struct AC_Automaton
    12 {
    13     int tot,son[N][27],fail[N],val[N],las[N],q[N],tm[152];
    14     void Init(){
    15         tot=0, memset(son,0,sizeof son), memset(val,0,sizeof val);
    16     }
    17     void Insert(char *s,int pos)
    18     {
    19         int l=strlen(s),x=0;
    20         for(int id,i=0; i<l; ++i)
    21         {
    22             id=s[i]-'a';
    23             if(!son[x][id]) son[x][id]=++tot;
    24             x=son[x][id];
    25         }
    26         val[x]=pos;
    27     }
    28     void Build()
    29     {
    30         int h=0,t=0;
    31         for(int i=0; i<S; ++i)
    32             if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i];
    33         while(h<t)
    34         {
    35             int x=q[h++];
    36             for(int v,i=0; i<S; ++i)
    37                 if(son[x][i])
    38                     fail[v=son[x][i]]=son[fail[x]][i],q[t++]=v,las[v]=val[fail[v]]?fail[v]:las[fail[v]];
    39                 else son[x][i]=son[fail[x]][i];
    40         }
    41     }
    42     void Query(char *p)
    43     {
    44         int l=strlen(p),res=0,x=0;
    45         memset(tm,0,sizeof tm);
    46         for(int i=0; i<l; ++i)
    47         {
    48             x=son[x][p[i]-'a'];
    49             for(int j=x; j; j=las[j]) ++tm[val[j]];
    50         }
    51         for(int i=1; i<=n; ++i) if(res<tm[i]) res=tm[i];
    52         printf("%d
    ",res);
    53         for(int i=1; i<=n; ++i) if(tm[i]==res) printf("%s
    ",s[i]);
    54     }
    55 }ac;
    56 
    57 int main()
    58 {
    59     while(scanf("%d",&n),n){
    60         ac.Init();
    61         for(int i=1; i<=n; ++i) scanf("%s",s[i]),ac.Insert(s[i],i);
    62         ac.Build(), scanf("%s",p), ac.Query(p);
    63     }
    64     return 0;
    65 }
    AC Automaton 加强版

    其它

    Hash

    判字符串相等

     粘个代码 POJ.2758.Checking the Text(Hash 二分答案)

     1 /*
     2 题意:给定一个字符串,有两种操作:在字符串中插入一个字符、询问某两个位置开始的LCP的长度 
     3 
     4 处理出Hash,LCP可以通过 二分+Hash 解决 
     5 由于修改次数很小,只有200,直接暴力修改重构 Hash 
     6 
     7 长度起名叫len,不要再用l了。。 
     8 */
     9 #include<cstdio>
    10 #include<cstring>
    11 #include<algorithm>
    12 #define ULL unsigned long long
    13 using namespace std;
    14 const int N=51000,base=131;
    15 
    16 int n,len,pos[N];
    17 char s[N];
    18 ULL pw[N],hs[N];
    19 
    20 void Init(int fr)
    21 {
    22     for(int i=fr;i<=len;++i)
    23         hs[i]=hs[i-1]*base+s[i];
    24 }
    25 ULL Get_Hash(int l,int r)
    26 {
    27     return hs[r]-hs[l-1]*pw[r-l+1];
    28 }
    29 int Solve(int x,int y)
    30 {
    31     int l=0,r=len-max(x,y)+1,m;
    32     while(l<=r)
    33     {
    34         m=l+r>>1;
    35         if(Get_Hash(x,x+m-1)==Get_Hash(y,y+m-1)) l=m+1;
    36         else r=m-1;
    37     }
    38     return r;
    39 }
    40 
    41 int main()
    42 {
    43 //    freopen("2758.in","r",stdin);
    44 
    45     pw[0]=1;
    46     for(int i=1;i<N;++i)
    47         pw[i]=pw[i-1]*base;
    48     
    49     scanf("%s",s+1);
    50     n=len=strlen(s+1);
    51     Init(1);
    52     for(int i=1;i<=n;++i)
    53         pos[i]=i;
    54     int t,a,b;char opt[5];
    55     scanf("%d",&t);
    56     while(t--)
    57     {
    58         scanf("%s",opt);
    59         if(opt[0]=='Q')
    60         {
    61             scanf("%d%d",&a,&b);
    62             printf("%d
    ",Solve(pos[a],pos[b]));
    63         }
    64         else
    65         {
    66             scanf("%s%d",opt,&a);
    67             ++len;
    68             if(a>len) a=len;
    69             memcpy(s+a+1,s+a,(len-a)*sizeof(char));
    70             s[a]=opt[0];
    71             for(int i=n;pos[i]>=a;--i)//每一位后移,暴力处理 
    72                 ++pos[i];
    73             Init(a);
    74         }
    75     }
    76     return 0;
    77 }
    Hash+二分

    莫队

    带修改莫队

    01分数规划

  • 相关阅读:
    卡顿检测
    FPS检测
    当检测到慢函数时,会在后台线程完成慢函数的分析
    慢函数检测
    对于没有复现onWindowFocusChange方法的Activity子类,插入一个onWindowFocusChange方法
    将totalCost用insurance的set方法set到保险总费用的字段中,然后进行插入操作。代码如下
    XML基础学习02<linq to xml>
    XML基础学习01
    Ajax学习记录
    数据迁移
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8676858.html
Copyright © 2020-2023  润新知