zoukankan      html  css  js  c++  java
  • 【 模_板 】 for NOIP 2017

    • 高精度

    #include <cstring>
    #include <cstdio>
    
    #define max(a,b) (a>b?a:b)
    
    inline void read(int &x)
    {
        x=0; register char ch=getchar();
        for(; ch>'9'||ch<'0'; ) ch=getchar();
        for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
    }
    const int N(1e5+5);
    
    namespace Bignum_ {
        struct Bignum {
            int num[2333]; // num[0] 表示数字位数 
            
            void init()    { memset(num,0,sizeof(num)); num[0]=1; }
            
            void Mul(int x) // 高精乗低精 
            {
                for(int i=1,ove=0; i<=num[0]; ++i)
                {
                    num[i]=num[i]*x+ove;
                    if(num[i]>9)
                    {
                        num[0]= max(num[0],i+1);
                        ove=num[i]/10;
                        num[i] %=10;
                    }
                    else ove=0;
                }
                for(; !num[num[0]]&&num[0]>1; ) num[0]--;
            }
            
            void Del(int x) //高精除低精 
            {
                for(int tt,t=0,i=num[0]; i; --i)
                {
                    tt=num[i];
                    num[i]=(tt+t*10)/x;
                    t=(t*10+num[i])%x;
                }
                for(; !num[num[0]]&&num[0]>1; ) num[0]--;
            }
            
            void print()
            {
                for(int i=num[0]; i; i--) printf("%d",num[i]);
            }
        }a,b;
        
        Bignum Add(Bignum a,Bignum b) //高精加高精 
        {
            Bignum c; c.num[0]=max(a.num[0],b.num[0]);
            for(int x=0,i=1; i<=c.num[0]; ++i)
            {
                c.num[i]=a.num[i]+b.num[i]+x;
                if(c.num[i]>9)
                {
                    x=c.num[i]/10; c.num[i]%=10;
                    c.num[0]=max(c.num[0],i+1);
                }
            }
            for(; !c.num[c.num[0]]&&c.num[0]>1; ) c.num[0]--;
            return c;
        }
        
        inline bool judge(Bignum a,Bignum b)
        {
            if(a.num[0]>b.num[0]) return 1;
            else if(a.num[0]<b.num[0]) return 0;
            else for(int i=a.num[0]; i; --i)
                    if(a.num[i]>b.num[i]) return 1;
                    else if(a.num[i]<b.num[i]) return 0;
            return 1;
        }
        
        Bignum Sub(Bignum a,Bignum b) // 高精-高精 
        {
            Bignum c; bool flag=0;
            c.num[0]=max(a.num[0],b.num[0]);
            if(judge(a,b)) //判谁做减数 
                for(int x=0,i=1; i<=c.num[0]; ++i)
                {
                    c.num[i]=a.num[i]-b.num[i];
                    if(c.num[i]<0) c.num[i+1]--,c.num[i]+=10;
                }
            else
            {
                for(int x=0,i=1; i<=c.num[0]; ++i)
                {
                    c.num[i]=b.num[i]-a.num[i];
                    if(c.num[i]<0) c.num[i+1]--,c.num[i]+=10;
                }
                flag=1;
            }
            for(; !c.num[c.num[0]]&&c.num[0]>1; ) c.num[0]--;
            if(flag) c.num[c.num[0]]=-c.num[c.num[0]];
            return c;
        }
    }
    
    int Presist()
    {
        
        return 0;
    }
    
    int Aptal=Presist();
    int main(int argc,char**argv){;}
    高精度
    • 数论知识

    #include <cstring>
    #include <cstdio>
    #include <cmath>
    
    #define LL long long
    
    inline void read(int &x)
    {
        x=0; register char ch=getchar();
        for(; ch>'9'||ch<'0'; ) ch=getchar();
        for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
    }
    
    const int mod(1e9+7);
    const int N(1000005);
    
    bool no_pri[N];
    LL fac[N],inv[N];
    int cnt,pri[N],phi[N];
    
    namespace Number_Theory {
        
        inline LL Mul(LL a,int b,int p) //慢速乗,防乗爆 
        {
            LL ret=0;
            for(; b; b>>=1, a<<=1,a%=p)
                if(b&1) ret+=a, ret%p;
            return ret;
        }
        
        inline LL Pow(LL a,int b,int p) // 快速幂 
        {
            LL ret=1;
            for(; b; b>>=1, a*=a,a%=p)
                if(b&1) ret*=a, ret%=p;
            return ret;
        }
        
        inline bool judge_ss(int x) // 根x 判素数 
        {
            if(x<2) return 0;
            for(int i=2; i*i<=x; ++i)
                if(x%i==0) return 0;
            return 1;
        }
        
        inline void Euller(int n) // 欧拉筛素数和欧拉函数 
        {
    /*        
            (1) 若(N%a==0 && (N/a)%a==0) 则有:E(N)=E(N/a)*a;
            (2) 若(N%a==0 && (N/a)%a!=0) 则有:E(N)=E(N/a)*(a-1);  
            其中a是N的质因数。
            关于欧拉函数还有以下性质:
            (1) phi[p]=p-1;  (p为素数);
            (2)若N=p^n(p为素数),则 phi[N]=(p-1)*p^(n-1);
    */        
            for(int i=2; i<=n; ++i)
            {
                if(!no_pri[i]) pri[++cnt]=i,phi[i]=i-1;
                for(int j=1; j<=cnt; ++j)
                {
                    if(pri[j]*i>n) break;
                    no_pri[pri[j]*i]=true;
                    if(i%pri[j]==0)
                    {
                        phi[i*pri[j]]=phi[i]*pri[j]; break;
                    }
                    else phi[i*pri[j]]=phi[i]*(pri[j]-1);
                }
            }
        }
        
        inline LL Phi(LL x)    // 欧拉函数 
        {
            LL ret=1;
            for(int i=2; i<=x; ++i)
            {
                if(x%i) continue;
                ret*=i-1, x/=i;
                for(; x%i==0; )
                    ret*=i,x/=i;
            }
            if(x>1) ret*=x-1;
            return ret;
        }
        
        inline LL exgcd(LL a,LL b,LL &x,LL &y) // 扩展欧几里得 
        {
            if(!b) { x=1,y=0; return a;}
            LL ret=exgcd(b,a%b,x,y),tmp=x;
            x=y; y=tmp-a/b*y; return ret;
        }
        
        inline LL Fermat(LL a,LL p) // p为素数 费马小定理 a^(p-1) = 1 mod p 
        {
            return Pow(a,p-2,p); // 逆元 
        }
        
        inline LL Pre_inv(int p) // a/b%mod --> a*inv(b,mod) 
        {
            fac[0]=fac[1]=inv[1]=1;
            for(int i=2; i<N; ++i)
            {
                fac[i]=1ll*fac[i-1]%p*i%p;
                inv[i]=1ll*inv[p%i]*(p-p/i)%p; //线性求逆元
                /*  拓展欧几里得求逆元 
                LL x,y,gcd=exgcd(i,mod,x,y);
                inv[i]= gcd==1 ?(x+mod)%mod :-1;
                */
                /* 欧拉函数求逆元 
                Euller();
                inv[i]=Fermat(i,mod);
                */
            }
        }
        
        inline LL CRT(LL *m,LL *p,int n) //中国剩余定理,互质不互质情况 
        {
            LL x,y,tmp,gcd,b,c;
            LL ret=m[1],a=p[1],mod;
            for(int i=2; i<=n; ++i)
            {
                tmp=m[i],b=p[i],c=tmp-ret;
                gcd=exgcd(a,b,x,y);
                if(c%gcd) return -1;
                x*=c/gcd, mod=b/gcd;
                for(x+=mod; x>=mod; ) x-=mod;
                ret+=a*x, a*=mod;
            }
            return ret?ret:(ret+a);
        }
        
        struct Matrix_fb {     // 矩阵优化菲波那切数列 
            LL e[2][2];
            void init_base()
            {
                e[0][0]=1;
                e[0][1]=1;
                e[1][0]=1;
                e[1][1]=0;
            }
            void init_ans()
            {
                e[0][0]=e[0][1]=1;
                e[1][0]=e[1][1]=0;
            }
            Matrix_fb operator * (Matrix_fb x) const 
            {
                Matrix_fb ret;
                for(int i=0; i<2; ++i)
                    for(int j=0; j<2; ++j)
                    {
                        ret.e[i][j]=0;
                        for(int k=0; k<2; ++k)
                          ret.e[i][j]+=e[i][k]*x.e[k][j],ret.e[i][j]%=mod;
                    }
                return ret;
            }
        }ans,base;
        
        inline LL Fibonacci(int n) 
        //斐波那契数列  gcd( f[a],f[b] )= f[ gcd(a,b) ], f[i]=f[i-1]+f[i-2]
        {
            double x=sqrt(5.0);
            return pow(((1+x)/2),n)/x - pow(((1-x)/2),n)/x; // 通式 
            if(n==1||n==2) return 1;
            for( n-=2; n; n>>=1,base=base*base)
                if(n&1) ans=ans*base;
            return ans.e[0][0];
        }
    }
    
    // 排列组合 
    namespace Permutations {
        
        inline void Pre_C(int n,int p) // 预处理组合数 
        {
            LL C[n][n];
            memset(C,0,sizeof(C));
            for(int i=1; i<n; ++i)
            {
                C[i][i]=C[i][0]=1;
                for(int j=1; j<i; ++j)
                    C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
            }
        }
        
        LL C(LL n,LL m,LL p)
        {
            if(m>n) return 0;
            LL t1=Number_Theory::Fermat(fac[m],p);
            LL t2=Number_Theory::Fermat(fac[n-m],p);
            return fac[n]%p*t1%p*t2%p;
        }
        
        LL Luc(LL n,LL m,LL p)
        {
            if(n<m) return 0;
            if(m==0) return 1;
            return (C(n%p,m%p,p))*Luc(n/p,m/p,p)%p;
        }
        
        inline void Use_luc(int n,int m,int p)
        // Lucas定理 Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p)  
        {
            Number_Theory:: Pre_inv(p);
            printf("%lld
    ",Luc(n,m,p));
        }
        
        inline int Catelan(int n) //卡特兰数 
        {
            int h[n]; memset(h,0,sizeof(h));
            h[0]=h[1]=1;
            for(int i=2; i<=n; ++i)
              for(int j=1; j<=i; ++j)
                  h[i]=h[i-j]*h[j-1]+h[i];
            return h[n];
        }
        
        inline int stirling(int n,int m)
        {
    /*
        stirling数,递推公式s[i][j]=s[i-1][j]*j+s[i-1][j-1]
        S(p,k)的一个组合学解释是:
            将p个物体划分成k个非空的不可辨别的(可以理解为盒子没有编号)集合的方法数。
        k!S(p,k)是把p个人分进k间有差别(如:被标有房号)的房间(无空房)的方法数。
        S(p,k)的递推公式是:S(p,k)=k*S(p-1,k)+S(p-1,k-1) ,1<= k<=p-1
        边界条件:S(p,p)=1 ,p>=0 S(p,0)=0 ,p>=1
        递推关系的说明:
        考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的不可辨别的集合,方法数为S(p-1,k-1);
        也可以前p-1种物品构成k个非空的不可辨别的集合,第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。
        注意:当m>n||m==0时直接输出0,!
    */
            int s[n][n]; memset(s,0,sizeof(s));
            for(int i=0; i<=n; ++i) s[i][i]=1;
            for(int i=1; i<=n; ++i)
              for(int j=1; j<=i; ++j)
                  s[i][j]=s[i-1][j-1]+s[i-1][j]*j;
            return (!m||m>n)?0:s[n][m];
        }
    }
    
    int Presist()
    {
        
        return 0;
    }
    
    int Aptal=Presist();
    int main(int argc,char**argv){;}
    数论知识
    • 图论知识

    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    
    inline void read(int &x)
    {
        x=0; register char ch=getchar();
        for(; ch>'9'||ch<'0'; ) ch=getchar();
        for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
    }
    const int INF(0x3f3f3f3f);
    const int N(1e5+5);
    const int M(1e6+5);
    
    // Graph_theory
    
    int sumedge,head[N];
    
    struct Edge {
        int v,next,w;
        Edge(int v=0,int next=0,int w=0):v(v),next(next),w(w){}
    }edge[M<<1];
        
    inline void ins(int u,int v,int w)
    {
        edge[++sumedge]=Edge(v,head[u],w),head[u]=sumedge;
        edge[++sumedge]=Edge(u,head[v],w),head[u]=sumedge;
    }
    
    namespace The_short_circuit {
        inline void Floyd(int n,int m)
        {
            int dis[555][555];
            for(int i=1; i<=n; ++i)
              for(int j=1; j<=n; ++j)
                dis[i][j]=INF*(i!=j);
                
            for(int k=1; k<=n; ++k)
             for(int i=1; i<=n; ++i)
              for(int j=1; j<=n; ++j)
               dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
        }
        
        int dis[N];
        bool inq[N],vis[N];
        
        inline void SPFA(int s,int n)
        {
            std::queue<int>que;
            for(int i=1; i<=n; ++i)
                inq[i]=0, dis[i]=INF;
            dis[s]=0; que.push(s);
            for(int u,v; !que.empty(); )
            {
                u=que.front(); que.pop(); inq[u]=0;
                for(int i=head[u]; i; i=edge[i].next)
                {
                    v=edge[i].v;
                    if(dis[v]>dis[u]+edge[i].w)
                    {
                        dis[v]=dis[u]+edge[i].w;
                        if(!inq[v]) que.push(v),inq[v]=1;
                    }
                }
            }
        }
        
        struct Node {
            int pos,dis;
            bool operator < (const Node&x)const
            {
                return dis>x.dis;
            }
        }u,v;
        
        inline void Dijkstra(int s,int n)
        {
            std::priority_queue<Node>que;
            for(int i=1; i<=n; ++i)
                vis[i]=0, dis[i]=INF;
            u.dis=dis[s]=0, u.pos=s; que.push(u);
            for(; !que.empty(); )
            {
                u=que.top(); que.pop();
                if(vis[u.pos]) continue;
                for(int i=head[u.pos]; i; i=edge[i].next)
                {
                    v.pos=edge[i].v;
                    if(dis[v.pos]>dis[u.pos]+edge[i].w)
                    {
                        dis[v.pos]=dis[u.pos]+edge[i].w;
                        v.dis= dis[v.pos];  que.push(v);
                    }
                }
            }
        }
    }
    
    namespace Negative_ring {
        bool vis[N];
        int dis[N];
        bool DFS(int u)
        {
            vis[u]=1;
            for(int v,i=head[u]; i; i=edge[i].next)
            {
                v=edge[i].v;
                if(dis[v]>dis[u]+edge[i].w)
                {
                    dis[v]=dis[u]+edge[i].w;
                    if(vis[v]||DFS(u))
                    {
                        vis[v]=0;
                        return 1;
                    }
                }
            }
            return vis[u]=0;
        }
    }
    
    namespace Tarjan_ {
        
        int sumcol,col[N];
        int tim,dfn[N],low[N];
        int stack[N],instack[N],top;
        int cutpoint[N],cutedge[M];
        
        void DFS(int u) //强联通分量,无向图加一个pre判断 
        {
            low[u]=dfn[u]=++tim;
            stack[++top]=u, instack[u]=1;
            for(int v,i=head[u]; i; i=edge[i].next)
            {
                v=edge[i].v;
                if(!dfn[v]) DFS(v), low[u]=min(low[u],low[v]);
                else if(instack[v]) low[u]=min(low[u],dfn[v]);
            }
            if(low[u]==dfn[u])
            {
                col[u]=++sumcol;
                for(; stack[top]!=u; top--)
                {
                    col[stack[top]]=sumcol;
                    instack[stack[top]]=false;
                }
                instack[u]=0, top--;
            }
        }
        
        void Tarjan(int u,int pre) //sumedge=-1 双联通 
        {
            int sumtredge=0; bool if_cutpoint=0;
            low[u]=dfn[u]=++tim;
            for(int v,i=head[u]; i; i=edge[i].next)
            {
                if((i^1)==pre) continue;
                if(!dfn[v])
                {
                    sumtredge++; Tarjan(v,i);
                    if(low[v]>=dfn[u]) if_cutpoint=1;
                    if(low[v]>dfn[u]) cutedge[i>>1]=1;
                    low[u]=min(low[u],low[v]);
                }
                else low[u]=min(low[u],dfn[v]);
            }
            if(!pre)
            {
                if(sumtredge>1) cutpoint[u]=1;
            }
            else if(if_cutpoint) cutpoint[u]=1;
        }
        
        inline void work(int n)
        {
            tim=0;sumcol=0;top=0;
            memset(dfn,0,sizeof(dfn));
            memset(low,0,sizeof(low));
            memset(stack,0,sizeof(stack));
            memset(instack,0,sizeof(instack));
        
            for(int i=1; i<=n; ++i)
                if(!dfn[i]) DFS(i);
            Tarjan(1,0);
        }
    }
    
    namespace MST_ {
        
        struct Edge {
            int u,v,w;
            bool operator < (const Edge&x)const
            {
                return w<x.w;
            }
        } road[M];
        int fa[N];
        
        int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); }
        
        inline void Kruskar(int m,int n)
        {
            for(int i=1; i<=n; ++i) fa[i]=i;
            std:: sort(road+1,road+m+1);
            int cnt=0, ret=0;    
            for(int fx,fy,i=1; i<=m; ++i)
            {
                fx=find(road[i].u),fy=find(road[i].v);
                if(fx==fy) continue; fa[fx]=fy;
                ret+=road[i].w; if(++cnt==n-1) break;
            }
            printf("%d
    ",ret);
        }
        
        inline void Prim(int n)
        {
            int ret=0,minn,vis[N],dis[N/10][N/10],d[N];
            for(int i=1; i<=n; ++i) vis[i]=0,d[i]=dis[1][i];
            vis[1]=1;
            for(int u,i=2; i<=n; ++i)
            {
                minn=INF;
                for(int j=2; j<=n; ++j)
                  if(!vis[j]&&minn>d[j]) minn=d[u=j];
                if(minn=INF) break;
                ret+=minn; vis[u]=1;
                for(int v=2; v<=n; ++v)
                  if(!vis[v]&&d[v]>dis[u][v]) d[v]=dis[u][v];
            }
            printf("%d
    ",ret);
        }
        
    }
    
    namespace Bisection_Graph {
    
        inline bool check(int s)
        {
            int col[N]; memset(col,-1,sizeof(col));
            col[s]=0; std::queue<int>que; que.push(s);
            for(int u,v; !que.empty(); )
            {
                u=que.front(); que.pop();
                for(int i=head[u]; i; i=edge[i].next)
                {
                    v=edge[i].v;
                    if(col[v]==-1)
                    {
                        col[v]=col[u]^1;
                        que.push(v);
                    }
                    else if(col[v]==col[u]) return 0;
                }
            }
            return true;
        }
        
        int match[N],map[N/10][N/10];
        int sumvis,vis[N];
        bool Get(int u,int n)
        {
            for(int v=1; v<=n; ++v)
              if(map[u][v]&&vis[v]!=sumvis)
              {
                vis[v]=sumvis;
                if(!match[v]||Get(match[v],n))
                {
                    match[v]=u;
                    return true;
                }
              }
            return false;
        }
        inline void Hungarian(int n)
        {
            int ans=0;
            for(int i=1; i<=n; ++i)
                sumvis++,ans+=Get(i,n);
            printf("%d
    ",ans);
        }
    }
    
    namespace Top_sort_ {
        inline void work(int n,int *rd)
        {
            std::queue<int>que;
            for(int i=1; i<=n; ++i)
                if(!rd[i]) que.push(i);
            for(int u,v; !que.empty(); )
            {
                u=que.front(); que.pop();
                for(int i=head[u]; i; i=edge[i].next)
                  if(--rd[edge[i].v]==0) que.push(edge[i].v);
            }
        }
    }
    
    int Presist()
    {
        
        return 0;
    }
    
    int Aptal=Presist();
    int main(int argc,char**argv){;}
    图论知识 
    • 数据结构

    #include <cstring>
    #include <cstdio>
    
    #define swap(a,b) {int c=a;a=b;b=c;}
    #define max(a,b) (a>b?a:b)
    
    inline void read(int &x)
    {
        x=0; register char ch=getchar();
        for(; ch>'9'||ch<'0'; ) ch=getchar();
        for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
    }
    const int N(1e5+5);
    
    /*
    Data_structure
    */
    
    int sum[N];
    namespace Tree_array {
        #define lowbit(x) (x&((~x)+1))
        inline void Update(int i,int x)
        {
            for(; i<N; i+=lowbit(i)) sum[i]+=x;
        }
        inline int Query(int i)
        {
            int ret=0;
            for(; i; i-=lowbit(i)) ret+=sum[i];
            return ret;
        }
    }
    
    struct Tree {
        bool flag;
        int l,r,mid,val;
    }tr[N<<2];
    namespace Line_segment_tree {
        
        #define lc (now<<1)
        #define rc (now<<1|1)
        #define mid (tr[now].l+tr[now].r>>1)
        
        void Update(int now)
        {
            tr[now].val=tr[lc].val+tr[rc].val;
        }
        
        void Build(int now,int l,int r)
        {
            tr[now].l=l, tr[now].r=r;
            if(l==r)
            {
                read(tr[now].val);
                tr[now].flag=0; return ;
            }
            Build(lc,l,mid),Build(rc,mid+1,r);
            Update(now);
        }
        
        void Pushdown(int now)
        {
            tr[lc].flag+=tr[now].flag;
            tr[lc].val+=tr[now].flag*(tr[lc].r-tr[lc].l+1);
            tr[rc].flag+=tr[now].flag;
            tr[rc].val+=tr[now].flag*(tr[rc].r-tr[rc].l+1);
            tr[now].flag=0;
        }
        
        void Change1(int now,int to,int x)
        {
            if(tr[now].l==tr[now].r)
            {
                tr[now].val=+x;
                tr[now].flag+=x;
                return ;
            }
            if(tr[now].flag) Pushdown(now);
            if(to<=mid) Change1(lc,to,x);
            else Change1(rc,to,x);
            Update(now);
        }
        
        void Change2(int now,int l,int r,int x)
        {
            if(tr[now].l==l&&tr[now].r==r)
            {
                tr[now].val+=x*(tr[now].r-tr[now].l+1);
                tr[now].flag+=x; return ;
            }
            if(tr[now].flag) Pushdown(now);
            if(r<=mid) Change2(lc,l,r,x);
            else if(l>mid) Change2(rc,l,r,x);
            else Change2(lc,l,mid,x),Change2(rc,mid+1,r,x);
            Update(now);
        }
        
        int Query(int now,int l,int r)
        {
            if(tr[now].l==l&&tr[now].r==r) return tr[now].val;
            if(tr[now].flag) Pushdown(now);
            if(r<=mid) return Query(lc,l,r);
            else if(l>mid) return Query(rc,l,r);
            else return Query(lc,l,mid)+Query(rc,mid+1,r);
            Update(now);
        }
    }
    
    int st[N][31],log2[N],t=0;
    namespace ST_ {
        inline void wokr(int n)
        {
            for(int i=1; i<=n; ++i)
                read(st[i][0]),log2[i]=(1<<t+1==i?++t:t);
            for(int j=1; 1<<j<=n; ++j)
              for(int i=1; i+(1<<j)<=n+1; ++i)
                  st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
        }
    }
    
    int head[N],sumedge;
    struct Edge {
        int v,next;
    }edge[N<<1];
    
    int size[N],dep[N];
    namespace LCA_1 {
        int dad[N],son[N],top[N];
        void DFS(int u,int depth)
        {
            size[u]=1;dep[u]=depth;
            for(int v,i=head[u]; i; i=edge[i].next)
            {
                v=edge[i].v;
                if(dad[u]==v) continue; dad[v]=u;
                DFS(v,depth+1), size[u]+=size[v];
                if(size[son[u]]<size[v]) son[u]=v;
            }
        }
        
        void DFS_(int u,int Top)
        {
            top[u]=Top; if(son[u]) DFS_(son[u],Top);
            for(int v,i=head[u]; i; i=edge[i].next)
            {
                v=edge[i].v;
                if(v!=son[u]&&v!=dad[u]) DFS_(v,v);
            }
        }
        
        inline int LCA(int x,int y)
        {
            for(; top[x]!=top[y]; x=dad[top[x]])
                if(dep[top[x]]<dep[top[y]]) swap(x,y);
            return dep[x]<dep[y]?x:y;
        }
        
    }
    
    namespace LCA_2 {
        int dad[N][31];
        
        void DFS(int u,int fa)
        {
            dep[u]=dep[fa]+1;
            for(int i=1; dad[u][i-1]; ++i)
                dad[u][i]=dad[dad[u][i-1]][i-1];
            for(int v,i=head[u]; i; i=edge[i].next)
                if(!dep[edge[i].v]) dad[edge[i].v][0]=u,DFS(v,u);
        }
        
        int LCA(int x,int y)
        {
            if(dep[x]>dep[y]) swap(x,y);
            for(int i=20; i>=0; --i)
              if(dep[dad[y][i]]>dep[dad[x][i]]) y=dad[y][i];
            if(x==y) return x;
            for(int i=20; i>=0; --i)
              if(dad[x][i]!=dad[y][i]) x=dad[x][i],y=dad[y][i];
            return dad[x][0];
        }
    }
    
    namespace Dai_quan_bing_cha_ji {
        int fa[N],val[N];
        int find(int x)
        {
            if(fa[x]==x) return x;
            int dad=find(fa[x]);
            val[x]+=val[fa[x]];
            return fa[x]=dad;
        }
        inline void combine(int x,int y)
        {
            x=find(x),y=find(y);
            if(x!=y) val[x]+=val[y],fa[x]=y;
        }
    }
    
    int trie[N<<2][27],tot;
    namespace Trie_Tree {
        inline void Build(char *s)
        {
            int len=strlen(s),now=0;
            for(int x,i=0; i<len; ++i)
            {
                x=s[i]-'a'+1;
                if(trie[now][x])
                     now=trie[now][x],trie[now][0]++;
                else now=trie[now][x]=++tot,trie[now][0]++;
            }
        }
        inline int find(char *s)
        {
            int len=strlen(s),now=0,p=0;
            for(; p<len; )
              if(trie[now][s[p]-'a'+1])
                now=trie[now][s[p]-'a'+1],++p;
              else return 0;
            return trie[now][0];
        }
    }
    
    namespace The_monotonous_queue {
        int que[N],head=1,tail,a[N];
        
        inline void work(int n,int m)
        {
            for(int i=1; i<=n; ++i)
            {
                read(a[i]);
                for(; head<=tail&&a[que[tail]]<=a[i]; ) tail--;
                for(que[++tail]=i; head<=tail&&i>m; ) head++; 
            }
        }
    }
    
    int Presist()
    {
    
        return 0;
    }
    
    int Aptal=Presist();
    int main(int argc,char**argv){;}
    数据结构
    • 字符串

    #include <cstring>
    #include <cstdio>
    
    const int N(1e6+5);
    
    char s[N],a[N];
    int p[N];
    
    namespace Kmp {
        inline void Get_next(char *s)
        {
            int len=strlen(s+1);
            for(int j=0,i=2; i<=len; p[i++]=j)
            {
                for(; j&&s[i]!=s[j+1]; ) j=p[j];
                if(s[i]==s[j+1]) j++;
            }
        }
        // 字符串最短长度 len-p[len] 
        inline void kmp(char *a,char *s)
        // 匹配子串位置 
        {
            Get_next(s);
            int la=strlen(a+1),ls=strlen(s+1);
            for(int j=0,i=1,k=0; i<=la; ++i)
            {
                for(; j&&a[i]!=s[j+1]; ) j=p[j];
                if(a[i]==s[j+1]) j++;
                if(j==ls) printf("%d
    ",i-j+1),j=p[j];
            }
        }
    }
    
    #define ull unsigned long long
    const int P(233);
    
    ull hs1[233],hs2[233];
    
    namespace Hash_ {
        inline ull Pow(ull a,int b)
        {
            ull ret=1;
            for(; b; b>>=1,a*=a)
                if(b&1) ret*=a;
            return ret;
        }
    
        inline bool Compare(int l,int r)
        {
            return hs1[r]-hs1[l]*Pow(P,r-l+1)==hs2[r-l+1];
        }
    
        inline void Get_hash(char *s)
        {
            int len=strlen(s+1);
            for(int i=1; i<=len; ++i)
                hs1[i]=hs1[i-1]*P+s[i]-'a';
        }
    }
    
    int Presist()
    {
        
        return 0;
    }
    
    int Aptal=Presist();
    int main(int argc,char**argv){;}
    字符串
  • 相关阅读:
    MMU讲解
    MiniCRT 64位 linux 系统移植记录:64位gcc的几点注意
    gprof使用介绍
    SQLite在多线程环境下的应用
    C++ Boost库简介
    GDB调试手册[转]
    data-ng-show 指令
    AngularJS THML DOM
    AngularJS 表格
    AngularJS XMLHttpRequest
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7794154.html
Copyright © 2011-2022 走看看