• 杨丰磊


    一般图带花树匹配:

    #include <bits/stdc++.h>
    
    using namespace std;
    #define N 230
    int nex[N],spo[N],w[N],q[N],vis[N],mark[N];
    vector<int>path[N];
    int n,r,u,to;
    int finds(int x){ return w[x]==x?x:w[x]=finds(w[x]); }
    void tog(int x,int y){
        x=finds(x),y=finds(y);
        if(x!=y)w[x]=y;
    }
    int findlca(int x,int y){
        static int t=0;
        t++;
        while(1){
            if(x){
                x=finds(x);
                if(vis[x]==t)return x;
                vis[x]=t;
                if(spo[x])x=nex[spo[x]];
                else x=0;
            }
            swap(x,y);
        }
    }
    void goup(int a,int p){
        while(a!=p){
            int b=spo[a],c=nex[b];
            if(finds(c)!=p)nex[c]=b;
            if(mark[b]==2)mark[q[r++]=b]=1;
            if(mark[c]==2)mark[q[r++]=c]=1;
            tog(a,b);tog(b,c);
            a=c;
        }
    }
    
    bool aug(int s){
        for(int i=1;i<=n;i++)nex[i]=-1,w[i]=i,mark[i]=0,vis[i]=-1;
        q[0]=s;r=1;mark[s]=1;
        for(int l=0;!spo[s]&&l<r;l++){
            int x=q[l];
            for(int i=0;i<(int)path[x].size();i++){
                int y=path[x][i];
                if(spo[x]!=y&&finds(x)!=finds(y)&&mark[y]!=2){
                    if(mark[y]==1){
                        int p=findlca(x,y);
                        if(finds(x)!=p)nex[x]=y;
                        if(finds(y)!=p)nex[y]=x;
                        goup(y,p);goup(x,p);
                    }else if (!spo[y]){
                        nex[y]=x;
                        for(int j=y;j;){
                            int k=nex[j],p=spo[k];
                            spo[j]=k;spo[k]=j;
                            j=p;
                        }
                        return true;
                    }else {
                        nex[y]=x;
                        mark[q[r++]=spo[y]]=1;
                        mark[y]=2;
                    }
                }
            }
        }
        return false;
    }
    int main()
    {
        cin>>n;
        while(scanf("%d%d",&u,&to)!=EOF){
            path[u].push_back(to);
            path[to].push_back(u);
        }
        int ans=0;
        for(int i=1;i<=n;i++)ans+=(!spo[i]&&aug(i));
        printf("%d
    ",ans*2);
        for(int i=1;i<=n;i++){
            if(spo[i])printf("%d %d
    ",i,spo[i]);
            spo[spo[i]]=0;
        }
    }
    

      

    分治FFT:

    #include <bits/stdc++.h>
    using namespace std;
    #define N 1000005
    #define go(i,a,b) for(int i=(a);i<=(b);i++)
    #define ms(a,b) memset(a,b,sizeof a)
    #define inf 0x3f3f3f3f
    #define mid (l+r)/2
    #define pi acos(-1.0)
    struct Complex{
        double x,y;
        Complex(double _x = 0.0, double _y = 0.0){
            x = _x; y = _y;
        }
        Complex operator -(const Complex &b)const{
            return Complex(x - b.x, y - b.y);
        }
        Complex operator +(const Complex &b)const{
            return Complex(x + b.x, y + b.y);
        }
        Complex operator *(const Complex &b)const{
            return Complex(x * b.x - y * b.y, x * b.y + y * b.x);
        }
    };
    
    void change(Complex y[],int len){
        int i,j,k;
        for(i = 1, j = len / 2; i < len - 1; i++){
            if(i < j) swap(y[i],y[j]);
            k = len / 2;
            while(j >= k){
                j -= k;
                k /= 2;
            }
            if(j < k) j += k;
        }
    }
    void fft(Complex y[],int len,int on){
        change(y,len);
        for(int h = 2; h <= len; h <<= 1){
            Complex wn(cos(-on*2*pi/h),sin(-on*2*pi/h));
            for(int j = 0; j < len; j += h){
                Complex w(1,0);
                for(int k = j; k < j + h / 2; k++){
                    Complex u = y[k];
                    Complex t = w * y[k + h / 2];
                    y[k] = u + t;
                    y[k + h / 2] = u - t;
                    w = w * wn;
                }
            }
        }
        if(on == -1){
            for(int i = 0; i < len; i++) y[i].x /= len;
        }
    }
    Complex A[N],B[N];
    int f[N],a[N],n;
    #define mod 313
    int cdq(int l,int r){
        if(l==r)return f[r];
        cdq(l,mid);
        int len=1;
        while(len/2<r-l+1)len*=2;
        go(i,0,len-1)A[i]=B[i]=Complex(0,0);
        go(i,l,mid)A[i-l].x=f[i];
        go(i,0,r-l)B[i].x=a[i];
        fft(A,len,1);fft(B,len,1);
        go(i,0,len-1)A[i]=A[i]*B[i];
        fft(A,len,-1);
        go(i,mid+1,r)(f[i]+=(int)(A[i-l].x+0.5))%=mod;
        cdq(mid+1,r);
        return f[r];
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF&&n){ ms(f,0);f[0]=1;
            go(i,1,n)scanf("%d",&a[i]),a[i]%=mod; printf("%d
    ",cdq(0,n));
        }
    }
    

      

    长链剖分:

    #include <bits/stdc++.h>
     
    using namespace std;
    #define N 1000005
    #define go(i,a,b) for(int i=(a);i<=(b);i++)
    #define pb push_back
    vector<int>path[N];
    int *f[N],son[N],len[N],ans[N],tmp[N],*id=tmp, n;
    void dfs(int u,int fa){
        for(int to:path[u]){
            if(to==fa)continue;
            dfs(to,u);
            if(len[to]>len[son[u]])son[u]=to;
        }
        len[u]=len[son[u]]+1;
    }
    void dpdfs(int u,int fa){
     
        f[u][0]=1;
        if(son[u])f[son[u]]=f[u]+1,dpdfs(son[u],u),ans[u]=ans[son[u]]+1;
        for(int to:path[u]){
            if(to==fa||to==son[u])continue;
            f[to]=id;id+=len[to];
            dpdfs(to,u);
            go(i,1,len[to]){
                f[u][i]+=f[to][i-1];
                if(f[u][i]>f[u][ans[u]]||(f[u][i]==f[u][ans[u]]&&i<ans[u]))ans[u]=i;
            }
        }
        if(f[u][ans[u]]==1)ans[u]=0;
    }
    int u,to;
    int main()
    {
        cin>>n;
        go(i,2,n)scanf("%d%d",&u,&to),path[u].pb(to),path[to].pb(u);
        dfs(1,0);f[1]=id;id+=len[1];
        dpdfs(1,0);
        go(i,1,n)printf("%d
    ",ans[i]);
        return 0;
    }
    

      

    斯坦纳树:

    #include <bits/stdc++.h>
    
    using namespace std;
    #define go(i,a,b) for(int i=(a);i<=(b);i++)
    #define dep(i,a,b) for(int i=(a);i>=(b);i--)
    #define inf 0x3f3f3f3f
    #define N 1010
    struct no{
        int to,n,w;
    };no eg[N*10];
    int h[N],is[N],tot=1,n,m,k;
    void add(int u,int to,int w){
        eg[tot]={to,h[u],w};h[u]=tot++;
        eg[tot]={u,h[to],w};h[to]=tot++;
    }
    int dp[N][1<<11],dk[1<<11];
    queue<int>q;
    void spfa(int s){
        go(i,1,n)if(dp[i][s]<inf)q.push(i),is[i]=1;
        while(!q.empty()){
            int x=q.front();q.pop();
            is[x]=0;
            for(int i=h[x];i;i=eg[i].n){
                int to=eg[i].to,w=eg[i].w;
                if(dp[to][s]>dp[x][s]+w){
                    dp[to][s]=dp[x][s]+w;
                    if(!is[to])q.push(to),is[to]=1;
                }
            }
        }
    }
    int a,b[N],hx[N],u,w,to;
    int main()
    {
        cin>>n>>m>>k;
        memset(dp,inf,sizeof(dp));
        memset(dk,inf,sizeof(dk));
        go(i,1,m)scanf("%d%d%d",&u,&to,&w),add(u,to,w);
        go(i,1,k)scanf("%d%d",&b[i],&a),dp[a][1<<(i-1)]=0,hx[b[i]]|=1<<(i-1);
        sort(b+1,b+k+1);
        int siz=unique(b+1,b+k+1)-b-1;
        int S=(1<<k)-1,SS=(1<<siz)-1;
        go(s,0,S){
            go(i,1,n)
                for(int t=s;t;t=(t-1)&s)
                    dp[i][s]=min(dp[i][s],dp[i][t]+dp[i][s^t]);
            spfa(s);
        }
        go(i,0,SS){
            int tmp=0;
            go(j,0,siz-1)if(i&(1<<j))tmp|=hx[b[j+1]];
            go(j,1,n)dk[i]=min(dk[i],dp[j][tmp]);
        }
        go(s,0,SS)
            for(int t=s;t;t=(t-1)&s)
                dk[s]=min(dk[s],dk[t]+dk[s^t]);
        cout<<dk[SS]<<endl;
        return 0;
    }
    

      

    #include <bits/stdc++.h>
     
    using namespace std;
     
    const int mod=1000000007;
    const int N=60;
    const int inf=0x3f3f3f3f;
    typedef pair<int,int> pii;
    int h[N],done[N],tot=1,n,m,k;
    pii operator*(const pii &A, const pii &B) { return {A.first+B.first, 1LL*A.second*B.second%mod}; }
     
    inline void upd(pii &A, const pii &B) {
        if(A.first > B.first) A = B;
        else if(A.first == B.first) A.second = (A.second+B.second)%mod;
    }
    pii dp[1<<12][N],dk[1<<12][N];
    priority_queue<pii,vector<pii>,greater<pii> >Q;
    vector<int>G[N];
    void dij(pii *g, pii *f) {
        for(int i = 0; i < n; i++) {
            if(g[i].first != inf) Q.push({g[i].first, i});
            done[i] = 0;
        }
        while(!Q.empty()) {
            pii t = Q.top(); Q.pop();
            int u = t.second;
            if(done[u]) continue;
            done[u] = 1;
            for(int v:G[u]) if(g[v].first >= g[u].first+1) {
                bool flag = g[v].first>g[u].first+1;
                upd(g[v], g[u]*pii(1, 1));
                upd(f[v], g[u]*pii(1, 1));
                if(flag) Q.push({g[v].first, v});
            }
        }
    }
    int main()
    {
        while(1){
            if(scanf("%d%d%d", &n, &m, &k) == -1) exit(0);
            int all=(1<<k)-1;
            for(int u = 0; u < n; u++) {
                G[u].clear();
                for(int S = 0; S <= all; S++) dp[S][u] = dk[S][u] = {inf, 0};
                if(u < k) dk[1<<u][u] = dp[1<<u][u] = {0, 1};
            }
            while(m--) {
                int u, v; scanf("%d%d", &u, &v);
                G[u-1].push_back(v-1), G[v-1].push_back(u-1);
            }
     
            for(int S = 0; S <= all; S++) {
            for(int u = 0; u < n; u++) for(int S0 = (S-1)&S; S0; S0 = (S0-1)&S)
                    if((S0&-S0) == (S&-S)) upd(dp[S][u], dk[S0][u]*dp[S^S0][u]);
                dij(dp[S], dk[S]);
            }
     
            printf("%d
    ",dp[all][0].second);
        }
        return 0;
    }
    

      

    按秩合并并查集:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=200000+100;
    int ans[N*2];
    struct UnF
    {
        int size[N],fa[N],mstack[N*4],top;
        void Init(int n)
        {
            for(int i=1; i<=n; i++)
                size[i]=1;
        }
        int FindFather(int x)
        {
            if(fa[x]==0)
                return x;
            return FindFather(fa[x]);
        }
        void Link(int x,int y)
        {
            mstack[++top]=0;
            int fa_x=FindFather(x),fa_y=FindFather(y);
            if(size[fa_x]>size[fa_y])
                swap(x,y),swap(fa_x,fa_y);
            if(fa_x==fa_y)
                return;
            mstack[top]=fa_x;
            fa[fa_x]=fa_y,size[fa_y]+=size[fa_x];
        }
        int Query(int x,int y)
        {
            if(FindFather(x)==FindFather(y))
                return true;
            return false;
        }
        void Undo()
        {
            if(mstack[top]==0)
            {
                top--;
                return;
            }
            size[fa[mstack[top]]]-=size[mstack[top]];
            fa[mstack[top]]=0;
            top--;
        }
    } unf;
    int n,m;
    
    #define pii pair<int,int>
    struct SegmentTree
    {
    #define mid ((now_l+now_r)>>1)
    #define lson (now<<1)
    #define rson (now<<1|1)
        vector <pii> w[N<<2];
        void Insert(int l,int r,int x,int y,int now,int now_l,int now_r)
        {
            if(now_l>=l and now_r<=r)
            {
                w[now].push_back(pii(x,y));
                return;
            }
            if(l<=mid)
                Insert(l,r,x,y,lson,now_l,mid);
            if(r>mid)
                Insert(l,r,x,y,rson,mid+1,now_r);
        }
        void dfs(int now,int now_l,int now_r)
        {
            if(now_l>now_r)
                return;
            for(pii x:w[now])
                unf.Link(x.first,x.second);
            if(now_l==now_r)
                ans[now_l]=unf.Query(1,n);
            else
            {
                dfs(lson,now_l,mid);
                dfs(rson,mid+1,now_r);
            }
            for(int i=0; i<int(w[now].size()); i++)
                unf.Undo();
        }
    #undef mid
    #undef lson
    #undef rson
    } sgt;
    struct no
    {
        int u, to,l,r;
    };
    no d[N];
    int lsx[N*2];
    #define go(i,a,b) for(int i=(a);i<=(b);i++)
    int main()
    {
        cin>>n>>m;
        unf.Init(n+1);
        go(i,1,m)
        {
            scanf("%d%d%d%d",&d[i].u,&d[i].to,&d[i].l,&d[i].r);
            lsx[i]=d[i].l,lsx[m+i]=d[i].r+1;
        }
        sort(lsx+1,lsx+m*2+1);
        int q=unique(lsx+1,lsx+m*2+1)-(lsx+1);
        go(i,1,m)
        {
            int l=lower_bound(lsx+1,lsx+q+1,d[i].l)-lsx;
            int r=lower_bound(lsx+1,lsx+q+1,d[i].r+1)-lsx-1;
            sgt.Insert(l,r,d[i].u,d[i].to,1,1,q);
        }
        sgt.dfs(1,1,q);
        int as=0;
        go(i,1,q)if(ans[i])
            as+=lsx[i+1]-lsx[i];
        cout<<as<<endl;
    }
    

      

    LCT:

    #include <bits/stdc++.h>
    
    using namespace std;
    #define N 200005
    #define ls c[x][0]
    #define rs c[x][1]
    struct LCT
    {
        int fa[N],ch[N][2],rev[N],sz[N],q[N];
        void init()
        {
            memset(ch,0,sizeof ch);
            memset(fa,0,sizeof fa);
            memset(sz,0,sizeof sz);
            memset(rev,0,sizeof rev);
        }
        inline bool isroot(int x)
        {
            return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
        }
        inline void pushup(int x)
        {
            sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
        }
        inline void pushdown(int x)
        {
            if(rev[x])
            {
                rev[x]=0;
                swap(ch[x][0],ch[x][1]);
                rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
            }
        }
        inline void Rotate(int x)
        {
            int y=fa[x],z=fa[y],l,r;
            if(ch[y][0]==x)
                l=0,r=l^1;
            else
                l=1,r=l^1;
            if(!isroot(y))
            {
                if(ch[z][0]==y)
                    ch[z][0]=x;
                else
                    ch[z][1]=x;
            }
            fa[x]=z;
            fa[y]=x;
            fa[ch[x][r]]=y;
            ch[y][l]=ch[x][r];
            ch[x][r]=y;
            pushup(y);
            pushup(x);
        }
        inline void splay(int x)
        {
            int top=1;
            q[top]=x;
            for(int i=x; !isroot(i); i=fa[i])
                q[++top]=fa[i];
            for(int i=top; i; i--)
                pushdown(q[i]);
            while(!isroot(x))
            {
                int y=fa[x],z=fa[y];
                if(!isroot(y))
                {
                    if((ch[y][0]==x)^(ch[z][0]==y))
                        Rotate(x);
                    else
                        Rotate(y);
                }
                Rotate(x);
            }
        }
        inline void access(int x)
        {
            for(int y=0; x; y=x,x=fa[x])
                splay(x),ch[x][1]=y,pushup(x);
        }
        inline void makeroot(int x)
        {
            access(x),splay(x),rev[x]^=1;
        }
        inline int findroot(int x)
        {
            access(x),splay(x);
            while(ch[x][0])
                x=ch[x][0];
            return x;
        }
        inline void split(int x,int y)
        {
            makeroot(x),access(y),splay(y);
        }
        inline void cut(int x,int y)
        {
            split(x,y);
            if(ch[y][0]==x)
                ch[y][0]=0,fa[x]=0;
        }
        inline void link(int x,int y)
        {
            makeroot(x),fa[x]=y,splay(x);
        }
    } lct;
    int fa[N][22],h[N];
    int n,m,l,rr,op,tot;
    inline int getfa(int u,int k)
    {
        for(int i=16; i>=0; i--)
            if((1<<i)<=k)
                u=fa[u][i],k-=(1<<i);
        return !u?n+1:u;
    }
    int v[N];
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            scanf("%d",&n);
            lct.init();
            for(int i=2; i<=n; i++)
                scanf("%d",&fa[i][0]);
            for(int j=1; j<=17; j++)
                for(int i=1; i<=n; i++)
                    fa[i][j]=fa[fa[i][j-1]][j-1];
            for(int i=1; i<=n; i++)
                scanf("%d",&v[i]);
            for(int i=1; i<=n; i++)
                lct.link(i,getfa(i,v[i]));
            scanf("%d",&m);
            for(int i=1; i<=m; i++)
            {
                scanf("%d",&op);
                if(op==1)
                {
                    scanf("%d",&rr);
                    lct.split(n+1,rr);
                    printf("%d
    ",lct.sz[rr]-1);
                }
                else
                {
                    scanf("%d %d",&l,&rr);
                    lct.cut(l,getfa(l,v[l]));
                    v[l]=rr;
                    lct.link(l,getfa(l,v[l]));
                }
            }
            //for(int i=1;i<=n;i++)cut(i,getfa(i,v[i]));
        }
        return 0;
    }
    

      

      

    欧拉回路路径树

    #include <bits/stdc++.h>
     
    using namespace std;
    #define N 300005
    #define go(i,a,b) for(int i=(a);i<=(b);i++)
    #define inf 0x3f3f3f3f
    #define mod 998244353
    #define ll long long
    int ny(int x){return x==1?1:1ll*ny(mod%x)*(mod-mod/x)%mod; }
    ll a[410][410],jx[N];
    int in[N],out[N],n;
    ll det(int n)//求前n行n列的行列式的值
        {
            go(i,1,n)go(j,1,n)a[i][j]=(a[i][j]%mod+mod)%mod;
            ll ret=1;
            for(int i=1;i<=n;i++)
            {
                for(int j=i+1;j<=n;j++)
                    while(a[j][i])
                    {
                        ll t=a[i][i]/a[j][i];
                        for(int k=i;k<=n;++k)
                            a[i][k]=((a[i][k]-a[j][k]*t)%mod+mod)%mod;
                        for(int k=i;k<=n;++k)
                            swap(a[i][k],a[j][k]);
                        ret=-ret;
                    }
                if(!a[i][i])
                    return 0;
                ret=ret*a[i][i]%mod;
            }
            ret=(ret%mod+mod)%mod;
            return ret;
        }
    int x,cas=1;
    int main()
    {
        jx[0]=1;go(i,1,N-1)jx[i]=jx[i-1]*i%mod;
        while(scanf("%d",&n)!=EOF){
            ll ans=1;
            go(i,0,n)go(j,0,n)a[i][j]=out[i]=in[i]=0;
            go(i,1,n){
                go(j,1,n){
                    scanf("%d",&x);
                    a[i][j]-=x;
                    a[j][j]+=x;
                    in[i]+=x;
                    out[j]+=x;
                    if(x)(ans*=ny(jx[x]))%=mod;
                }
                (ans*=(jx[in[i]-1]+mod)%mod)%=mod;
            }
            int fl=1;
            go(i,1,n)if(in[i]!=out[i])fl=0;
            (ans*=det(n-1))%=mod;
           // cout<<ans<<endl;
            printf("Case #%d: %lld
    ",cas++,ans*in[1]*fl%mod);
        }
        return 0;
    }
    

      

     李超树

    #include <bits/stdc++.h>
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define N 200005
    #define ll long long
    #define mod 1000000007
    #define go(i,a,b) for(int i=(a);i<=(b);i++)
    #define dep(i,a,b) for(int i=(a);i>=(b);i--)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define ld long double
    #define pii pair<int,int>
    #define vi vector<int>
    #define add(a,b) (a+=(b)%mod)%=mod
    #define lowb(x,c,len) lower_bound(c+1,c+len+1,x)-c
    #define uppb(x,c,len) upper_bound(c+1,c+len+1,x)-c
    #define ls i*2+1
    #define rs i*2+2
    #define mid (l+r)/2
    #define lson l,mid,ls
    #define rson mid+1,r,rs
    #define root 1,n,0
    #define ms(a,b) memset(a,b,sizeof a)
    #define muti int T;cin>>T;while(T--)
    int t[N*4];
    ld k[N],b[N];
    
    ld lsx[N],x[N],y[N];
    ld f(int id,int x){return k[id]*lsx[x]+b[id]; }
    void updata(int x,int l,int r,int i){
        if(f(x,l)>=f(t[i],l)&&f(x,r)>=f(t[i],r))return ;
        if(f(x,l)<f(t[i],l)&&f(x,r)<=f(t[i],r)){t[i]=x;return ;}
        if(f(x,l)<f(t[i],l)){
            if(f(x,mid)<f(t[i],mid)){
                updata(t[i],rson);
                t[i]=x;
            }
            else updata(x,lson);
        }
        else {
            if(f(x,mid)<f(t[i],mid)){
                updata(t[i],lson);
                t[i]=x;
            }
            else updata(x,rson);
        }
    }
    ld query(int x,int l,int r,int i){
        ld res=f(t[i],x);
        if(l==r)return res;
        if(x<=mid)res=min(res,query(x,lson));
        else res=min(res,query(x,rson));
        return res;
    }
    ld w,c,ans,sum;int n;
    ld as(int i){ return lsx[i]+(w-sum-c)/k[i]; }
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>w>>n>>c;
        k[0]=1,b[0]=0;
        go(i,1,n)cin>>lsx[i]>>x[i]>>y[i];
        go(i,1,n){
            sum=query(i,root);
            k[i]=y[i]/x[i];b[i]=sum-k[i]*lsx[i]+c;
            updata(i,root);
            if(sum+c<w)ans=max(ans,as(i));
        }
        cout<<fixed<<setprecision(9)<<ans<<endl;
    }
    
  • 相关阅读:
    Windows共享作为公司文件服务器的案例
    关于限制域用户登陆计算机的几点总结
    防止加入域主机脱离域的控制(管理员权限)
    域组策略禁止执行指定软件
    域用户执行金蝶K/3报错解决方法
    WinXP/Win7/Win8本地用户配置文件迁移至域用户
    Windows批处理:请求远程协助
    浅谈JavaScript闭包
    新蛋那几月
    JavaScript 32位整型无符号操作
  • 原文地址:https://www.cnblogs.com/SDUTNING/p/11543706.html
Copyright © 2020-2023  润新知