zoukankan      html  css  js  c++  java
  • $My$ $template$(持续更新)

    树链剖分:(来源:树的统计)

    #include<bits/stdc++.h>
    #define rint register int
    using namespace std;
    inline void read(int &A)
    {
        A=0;int B=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')B=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){A=(A<<3)+(A<<1)+ch-'0';ch=getchar();}
        A=A*B;return ;
    }
    int n,q,v[60004],w[30004],nxt[60004],first[30004],tot;
    int f[30004],d[30004],siz[30004],son[30004];
    int id[30004],rk[30004],cnt,tp[30004],ans;
    char ch[13];
    struct node{int k,mx;}t[30004<<2];
    inline void build_line(int uu,int vv)
    {
        v[++tot]=vv,nxt[tot]=first[uu];
        first[uu]=tot;
    }
    inline void dfs(int x,int fa,int dep)
    {
        f[x]=fa,d[x]=dep,siz[x]=1;
        for(rint i=first[x];i;i=nxt[i])
        {
            int y=v[i];if(y==fa)continue;
            dfs(y,x,dep+1);siz[x]+=siz[y];
            if(siz[y]>siz[son[x]])son[x]=y;
        }
        return ;
    }
    inline void Dfs(int x,int t)
    {
        tp[x]=t,id[x]=++cnt,rk[cnt]=x;
        if(!son[x])return ;Dfs(son[x],t);
        for(rint i=first[x];i;i=nxt[i])
            if(v[i]!=son[x]&&v[i]!=f[x])
                Dfs(v[i],v[i]);
        return ;
    }
    inline void update(int k)
    {
        t[k].k=t[k<<1].k+t[k<<1|1].k;
        t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
        return ;
    }
    inline void build(int k,int l,int r)
    {
        if(l==r){t[k].k=t[k].mx=w[rk[l]];return ;}
        int mid=(l+r)>>1;
        build(k<<1,l,mid);build(k<<1|1,mid+1,r);
        update(k);return ;
    }
    inline int Qsum(int k,int l,int r,int L,int R)
    {
        if(L<=l&&r<=R)return t[k].k;
        int mid=(l+r)>>1,res=0;
        if(L<=mid)res+=Qsum(k<<1,l,mid,L,R);
        if(R>mid)res+=Qsum(k<<1|1,mid+1,r,L,R);
        return res;
    }
    inline int Qmax(int k,int l,int r,int L,int R)
    {
        if(L<=l&&r<=R)return t[k].mx;
        int mid=(l+r)>>1,res=-0x7fffffff;
        if(L<=mid)res=max(res,Qmax(k<<1,l,mid,L,R));
        if(R>mid)res=max(res,Qmax(k<<1|1,mid+1,r,L,R));
        return res;
    }
    inline void change(int k,int l,int r,int p,int dat)
    {
        if(l==r){t[k].k=t[k].mx=dat;return ;}
        int mid=(l+r)>>1;
        if(p<=mid)change(k<<1,l,mid,p,dat);
        else change(k<<1|1,mid+1,r,p,dat);
        update(k);return ;
    }
    inline int get_sum(int x,int y)
    {
        int Sum=0,fx=tp[x],fy=tp[y];
        while(fx!=fy)
        {
            if(d[fx]>=d[fy])
            {
                Sum+=Qsum(1,1,n,id[fx],id[x]);
                x=f[fx],fx=tp[x];
            }
            else
            {
                Sum+=Qsum(1,1,n,id[fy],id[y]);
                y=f[fy],fy=tp[y];
            }
        }
        if(id[x]<=id[y])Sum+=Qsum(1,1,n,id[x],id[y]);
        else Sum+=Qsum(1,1,n,id[y],id[x]);
        return Sum;
    }
    inline int get_max(int x,int y)
    {
        int Max=-0x7fffffff,fx=tp[x],fy=tp[y];
        while(fx!=fy)
        {
            if(d[fx]>=d[fy])
            {
                Max=max(Max,Qmax(1,1,n,id[fx],id[x]));
                x=f[fx],fx=tp[x];
            }
            else
            {
                Max=max(Max,Qmax(1,1,n,id[fy],id[y]));
                y=f[fy],fy=tp[y];
            }
        }
        if(id[x]<=id[y])Max=max(Max,Qmax(1,1,n,id[x],id[y]));
        else Max=max(Max,Qmax(1,1,n,id[y],id[x]));
        return Max;
    }
    int main()
    {
    //    freopen("count1.in","r",stdin);
    //    freopen("my.out","w",stdout);
        read(n);
        for(rint i=1,ST,EN;i<n;++i)
        {
            read(ST),read(EN);
            build_line(ST,EN);
            build_line(EN,ST);
        }
        for(rint i=1;i<=n;++i)read(w[i]);
        dfs(1,0,1);Dfs(1,1);build(1,1,n);
        read(q);
        for(rint i=1,uu,vv;i<=q;++i)
        {
            scanf("%s",ch);
            if(ch[0]=='C')
            {
                read(uu),read(vv);
                change(1,1,n,id[uu],vv);
            }
            else
            {
                ans=0;read(uu),read(vv);
                if(ch[1]=='M')ans=get_max(uu,vv);
                else ans=get_sum(uu,vv);
                printf("%d
    ",ans);
            }
        }
    }
    树链剖分模板

    tarjan点双

    inline void tarjan(int x)
    {
        dfn[x]=low[x]=++cnt;s.push(x);
        if(x==root && firsty[x]==0)
        {
            dcc[++totq].clear();
            dcc[totq].push_back(x);
            return ;
        }
        int flag=0;
        for(rint i=firsty[x];i;i=edge[i].nxt)
        {
            int y=edge[i].v;
            if(!dfn[y])
            {
                tarjan(y);low[x]=min(low[x],low[y]);
                if(low[y]>=dfn[x])
                {
                    flag++;
                    if(x!=root||flag>1)cut[x]=true;
                    totq++;int z;
                    dcc[totq].clear();
                    do{
                        z=s.top();s.pop();
                        dcc[totq].push_back(z);
                    }while(z!=y);
                    dcc[totq].push_back(x);
                }
            }
            else low[x]=min(low[x],dfn[y]);
        }
    }
    tarjan点双模板

    二分图匹配(带注释)

    int point(int u)//这个函数的作用是寻找增广路和更新cx,xy数组,如果找到了增广路,函数返回1,找不到,函数返回0。
    {
        for(int v=1;v<=ny;v++)//依次遍历右边的所有顶点
        {
            if(e[u][v]&&!visited[v])//条件一:左边的u顶点和右边的v顶点有连通边,条件二:右边的v顶点在没有被访问过,这两个条件必须同时满足
            {
                visited[v]=1;//将v顶点标记为访问过的
                if(cy[v]==-1||point(cy[v]))//条件一:右边的v顶点没有左边对应的匹配的点,条件二:以v顶点在左边的匹配点为起点能够找到一条增广路(如果能够到达条件二,说明v顶点在左边一定有对应的匹配点)。
                {
                    cx[u]=v;//更新cx,cy数组
                    cy[v]=u;
                    return 1;
                }
            }
        }
        return 0;//如果程序到达了这里,说明对右边所有的顶点都访问完了,没有满足条件的。
    }
    二分图匹配模板

    中国剩余定理

    LL exgcd(LL a,LL b,LL &x,LL &y)
    {
        if(!b)
        {
            x=1;y=0;
            return a;
        }
        LL res=exgcd(b,a%b,x,y);
        LL t=x;
        x=y;
        y=t-a/b*x;
        return res;
    }
    LL China()
    {
        LL m=1;
        LL res=0;
        LL x,y;
        for(rint i=1;i<=n;i++)m*=a[i];
        for(rint i=1;i<=n;i++)
        {
            LL tmp=m/a[i];
            exgcd(tmp,a[i],x,y);
            res=(res+tmp*x*b[i])%m;
        }
        res=(res+m)%m;
        return res;
    }
    中国剩余定理模板
  • 相关阅读:
    tp5 url 线上访问 在nginx 上 出现404错误,解决办法(1.80nginx 配置 pathInfo)
    Windows下配置nginx+php(wnmp)
    windows向github提交代码
    改变图片尺寸
    mysql字符编码的设置以及mysql中文乱码的解决方法
    wamp升级php7
    C++Primer第五版——习题答案和解析
    Ubuntu16.04下安装显卡驱动记录
    Ubuntu环境下No module named '_tkinter'错误的解决
    TensorFlow:NameError: name ‘input_data’ is not defined
  • 原文地址:https://www.cnblogs.com/xingmi-weiyouni/p/11675209.html
Copyright © 2011-2022 走看看