Infiniti

   :: 首页  :: 新随笔  ::  ::  :: 管理

一般图带花树匹配:

#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\n",ans*2);
    for(int i=1;i<=n;i++){
        if(spo[i])printf("%d %d\n",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\n",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\n",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\n",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\n",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\n",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;
}

 

posted on 2019-09-18 17:06  自由缚  阅读(176)  评论(0编辑  收藏  举报