• NOI考前乱写


    还有13天NOI,把各种乱七八糟的算法都重新过一遍还是比较有必要的。。。

    //HDU 5046 Airport
    //DancingLink
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 110
    #define MAXD MAXN*MAXN
    #define INF 0x3f3f3f3f
    #define LL "%lld"
    typedef long long qword;
    struct point
    {
            qword x,y;
    };
    point pl[MAXN];
    qword dis(point p1,point p2)
    {
            return abs(p1.x-p2.x)+abs(p1.y-p2.y);
    }
    int L[MAXD],R[MAXD],U[MAXD],D[MAXD];
    int ptr[MAXN];
    int tot[MAXN];
    int col[MAXD];
    int topd=0;
    int head=0;
    void cover(int now)
    {
            for (int i=R[now];i!=now;i=R[i])
            {
                    for (int j=U[i];j!=i;j=U[j])
                    {
                            L[R[j]]=L[j];
                            R[L[j]]=R[j];
                    }
            }
            for (int j=U[now];j!=now;j=U[j])
            {
                    L[R[j]]=L[j];
                    R[L[j]]=R[j];
            }
    }
    void recover(int now)
    {
            for (int i=R[now];i!=now;i=R[i])
                    for (int j=U[i];j!=i;j=U[j])
                            L[R[j]]=R[L[j]]=j;
            for (int j=U[now];j!=now;j=U[j])
                    L[R[j]]=R[L[j]]=j;
    }
    int vv[MAXN];
    int ff()
    {
            int ret=0;
            for (int i=R[head];i!=head;i=R[i])
                    vv[col[i]]=true;
            for (int i=R[head];i!=head;i=R[i])
            {
                    if (vv[col[i]])
                    {
                            ret++;
                            for (int j=D[i];j!=i;j=D[j])
                            {
                                    for (int k=R[j];k!=j;k=R[k])
                                    {
                                            vv[col[k]]=false;
                                    }
                            }
                    }
            }
            return ret;
    }
    bool solve(int trst)
    {
            if (L[head]==R[head] && L[head]==head)return true;
            if (!trst)return false;
            if (trst<ff())return false;
            pair<int,int> mnv=make_pair(INF,0);
            for (int i=R[head];i!=head;i=R[i])
                    mnv=min(mnv,make_pair(tot[i],i));
            int now=mnv.second;
            for (int i=D[now];i!=now;i=D[i])
            {
                    cover(i);
                    if (solve(trst-1))return true;
                    recover(i);
            }
            return false;
    }
    
    int main()
    {
            freopen("input.txt","r",stdin);
            int nn;
            int n,m;
            int x,y,z;
            scanf("%d",&nn);
            int caseid=0;
            while (nn--)
            {
                    caseid++;
                    scanf("%d%d",&n,&m);
                    for (int i=1;i<=n;i++)
                            scanf(LL LL ,&pl[i].x,&pl[i].y);
                    memset(ptr,0,sizeof(ptr[0])*(n+10));
                    memset(tot,0,sizeof(tot[0])*(n+10));
                    qword l=-1,r=1ll<<33,mid;
                    while (l+1<r)
                    {
                            mid=(l+r)>>1;
                            topd=0;
                            head=++topd;
                            L[head]=R[head]=head;
                            for (int i=1;i<=n;i++)
                            {
                                    int np=++topd;
                                    col[np]=i;
                                    R[np]=head;
                                    L[np]=L[head];
                                    L[R[np]]=np;
                                    R[L[np]]=np;
                                    D[np]=U[np]=np;
                                    ptr[i]=np;
                            }
                            for (int i=1;i<=n;i++)
                            {
                                    int last=0;
                                    for (int j=1;j<=n;j++)
                                    {
                                            if (dis(pl[i],pl[j])<=mid)
                                            {
                                                    int np=++topd;
                                                    col[np]=j;
                                                    tot[ptr[j]]++;
                                                    D[np]=ptr[j];
                                                    U[np]=U[ptr[j]];
                                                    D[U[np]]=U[D[np]]=np;
                                                    if (!last)
                                                    {
                                                            L[np]=R[np]=np;
                                                    }else
                                                    {
                                                            L[np]=last;
                                                            R[np]=R[last];
                                                            L[R[np]]=R[L[np]]=np;
                                                    }
                                                    last=np;
                                            }
                                    }
                            }
                            if (solve(m))
                            {
                                    r=mid;
                            }else
                            {
                                    l=mid;
                            }
                    }
                    printf("Case #%d: "LL"
    ",caseid,r);
            }
    }
    DancingLink

    半年没写DLX了,还能在30分钟内写出来,感觉不错。

    DLX分为精确覆盖和完全覆盖,两者的区别大概是在cover和recover之中。

    另外DLX也是需要剪枝的。

    //bzoj 1135
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 210000
    #define MAXT MAXN*5
    #define lch (now<<1)
    #define rch (now<<1^1)
    #define smid ((l+r)>>1)
    typedef long long qword;
    struct sgt_node
    {
            int lc,rc;
            qword lx,rx,mx;
            qword sum;
    }sgt[MAXT];
    void update(int now)
    {
            sgt[now].lx=max(sgt[lch].lx,sgt[lch].sum+sgt[rch].lx);
            sgt[now].rx=max(sgt[rch].rx,sgt[rch].sum+sgt[lch].rx);
            sgt[now].sum=sgt[lch].sum+sgt[rch].sum;
            sgt[now].mx=max(max(sgt[lch].mx,sgt[rch].mx),sgt[lch].rx+sgt[rch].lx);
    }
    void Build_sgt(int now,int l,int r,int v)
    {
            if (l==r)
            {
                    sgt[now].sum=v;
                    sgt[now].lx=sgt[now].rx=sgt[now].mx=v;
                    return ;
            }
            Build_sgt(lch,l,smid,v);
            Build_sgt(rch,smid+1,r,v);
            update(now);
    }
    void Modify_sgt(int now,int l,int r,int pos,int v)
    {
            if (l==r)
            {
                    sgt[now].sum+=v;
                    sgt[now].lx+=v;
                    sgt[now].rx+=v;
                    sgt[now].mx+=v;
                    return ;
            }
            if (pos<=smid)
                    Modify_sgt(lch,l,smid,pos,v);
            else
                    Modify_sgt(rch,smid+1,r,pos,v);
            update(now);
    }
    
    int main()
    {
            freopen("input.txt","r",stdin);
            int n,m,t,d;
            int x,y;
            scanf("%d%d%d%d",&n,&m,&t,&d);
            Build_sgt(1,1,n,-t);
            for (int i=0;i<m;i++)
            {
                    scanf("%d%d",&x,&y);
                    Modify_sgt(1,1,n,x,y);
                    if (sgt[1].mx>(qword)t*d)
                    {
                            printf("NIE
    ");
                    }else
                    {
                            printf("TAK
    ");
                    }
            }
    
    Hall

    hall定理用于二分图匹配相关问题,在要求方案时用贪心或匈牙利算法,运用hall定理有利于优化时间复杂度。

    //bzoj 3270
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cassert>
    #include<cmath>
    using namespace std;
    #define MAXN 1010
    #define MAXV MAXN
    #define MAXE MAXN*20
    typedef double real;
    const real eps = 1e-7;
    
    struct Edge
    {
            int np;
            Edge *next;
    }E[MAXE],*V[MAXV];
    int tope=-1;
    void addedge(int x,int y)
    {
            E[++tope].np=y;
            E[tope].next=V[x];
            V[x]=&E[tope];
    }
    real ps[MAXN];
    real mat[MAXN][MAXN];
    real res[MAXN];
    int deg[MAXN];
    
    int main()
    {
            freopen("input.txt","r",stdin);
            int n,m;
            int a,b;
            int x,y,z;
            scanf("%d%d",&n,&m);
            scanf("%d%d",&a,&b);
            a--;b--;
            for (int i=0;i<m;i++)
            {
                    scanf("%d%d",&x,&y);
                    x--;y--;
                    addedge(x,y);
                    addedge(y,x);
                    deg[x]++;
                    deg[y]++;
            }
            for (int i=0;i<n;i++)
                    scanf("%lf",&ps[i]);
            for (int i=0;i<n;i++)
            {
                    for (int j=0;j<n;j++)
                    {
                            if (i==j)
                            {
                                    mat[i*n+j][i*n+j]=1;
                                    continue;
                            }
                            Edge *ne1,*ne2;
                            for (ne1=V[i];ne1;ne1=ne1->next)
                                    for (ne2=V[j];ne2;ne2=ne2->next)
                                            mat[ne1->np*n+ne2->np][i*n+j]=-1*(1-ps[i])*(1-ps[j])/deg[i]/deg[j];
                            Edge *ne;
                            for (ne=V[i];ne;ne=ne->next)
                                    mat[ne->np*n+j][i*n+j]=-1*ps[j]*(1-ps[i])/deg[i];
                            for (ne=V[j];ne;ne=ne->next)
                                    mat[i*n+ne->np][i*n+j]=-1*(1-ps[j])*ps[i]/deg[j];
                            mat[i*n+j][i*n+j]=1-ps[i]*ps[j];
                            mat[i*n+j][n*n]=0;
                    }
            }
            mat[a*n+b][n*n]=1;
            int l=n*n;
            for (int i=0;i<l;i++)
            {
                    int x=-1;
                    for (int j=i;j<=l;j++)
                    {
                            if (abs(mat[j][i])>eps)
                                    x=j;
                    }
                    assert(x!=-1);
                    if (x!=i)
                            for(int j=0;j<=l;j++)
                                    swap(mat[i][j],mat[x][j]);
                    for (int j=i+1;j<l;j++)
                    {
                            real tmp=mat[j][i]/mat[i][i];
                            for (int k=i;k<=l;k++)
                            {
                                    mat[j][k]-=mat[i][k]*tmp;
                            }
                    }
            }
            for (int i=l-1;i>=0;i--)
            {
                    real tmp=mat[i][n*n];
                    for (int j=i+1;j<n*n;j++)
                            tmp-=res[j]*mat[i][j];
                    res[i]=tmp/mat[i][i];
            }
            for (int i=0;i<n;i++)
                    printf("%.6lf ",res[i*n+i]);
    }
    概率1

    概率期望dp以及高消在很多时候都是可以转化的,而适当的转化会使思维难度大大降低。

    //Miller Rabin
    //HDU 2138
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long qword;
    qword pow_mod(qword x,qword y,int mod)
    {
            qword ret=1%mod;
            while (y)
            {
                    if (y&1)ret=ret*x%mod;
                    x=x*x%mod;
                    y>>=1;
            }
            return ret;
    }
    
    bool MillerRabin(qword a,int n)
    {
            int x=n-1,y=0;
            while ((x&1)==0)x>>=1,y++;
            a=pow_mod(a,x,n);
            int pe=a;
            for (int i=0;i<y;i++)
            {
                    pe=a;
                    a=a*a%n;
                    if (a==1 && pe!=n-1 && pe!=1)return false;
            }
            return a==1?true:false;
    }
    
    int main()
    {
        //    freopen("input.txt","r",stdin);
            int n;
            int x;
            int s[6]={2,3,5,7,17,61};
            while (~scanf("%d",&n))
            {
                    int ans=0;
    
                    for (int i=0;i<n;i++)
                    {
                            scanf("%d",&x);
                            if (x==1)
                            {
                                    continue;
                            }else if (x==2)
                            {
                                    ans++;
                                    continue;
                            }
                            bool flag=true;
                            for (int j=0;j<6;j++)
                            {
                                    if (s[j]>=x)continue;
                                    if (!MillerRabin(s[j],x))
                                    {
                                            flag=false;
                                            break;
                                    }
                            }
                            if (flag)
                            {
                                    ans++;
                            }
                    }
                    printf("%d
    ",ans);
           
    Miller Rabin

    这种时候还理解什么,赶快背啊!

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    #define MAXN 110000
    #define MAXM 210
    #define BIG 1000000000000000LL
    typedef long long qword;
    int a[MAXN];
    qword s[MAXN];
    qword dp[2][MAXN];
    struct point
    {
            qword x,y;
    };
    qword area(point p1,point p2,point p3)
    {
            return (p1.x-p2.x)*(p1.y-p3.y) - (p1.y-p2.y)*(p1.x-p3.x);
    }
    point q[MAXN];
    
    int main()
    {
            freopen("input.txt","r",stdin);
            freopen("output.txt","w",stdout);
            int n,m;
            scanf("%d%d",&n,&m);
            for (int i=1;i<=n;i++)
            {
                    scanf("%d",&a[i]);
                    //if (!a[i])i--,n--;
            }
            for (int i=1;i<=n;i++)
                    s[i]=s[i-1]+a[i];
            for (int i=0;i<2;i++)
                    for (int j=0;j<=n;j++)
                            dp[i][j]=-BIG;
            int head,tail;
            point pt;
            dp[0][0]=0;
            for (int i=1;i<=m;i++)
            {
                    head=0;
                    tail=-1;
                    for (int j=1;j<=n;j++)
                    {
                            pt.x=s[j-1];
                            pt.y=-s[n]*s[j-1]+dp[(i&1)^1][j-1];
                            while (head<tail && area(q[tail-1],q[tail],pt)>=0)
                            {
                                    if (area(q[tail-1],q[tail],pt)==0)
                                    {
                                            cout<<"haha"<<endl;
                                    }
                                    tail--;
                            }
                            q[++tail]=pt;
                            while (head<tail && s[j]*q[head].x+q[head].y<=s[j]*q[head+1].x+q[head+1].y)
                                    head++;
                            dp[i&1][j]=s[j]*q[head].x+q[head].y + s[n]*s[j]-s[j]*s[j];
            //                printf("%lld ",dp[i&1][j]);
                    }
                    dp[i&1][0]=-BIG;
            //        printf("
    ");
            }
            qword ans=0;
            for (int i=1;i<=n;i++)
                    ans=max(ans,dp[m&1][i]);
            printf("%lld
    ",ans);
    }
    斜率优化
    //POJ 1160
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 3100
    #define MAXM 40
    #define INF 0x3f3f3f3f
    int w[MAXN][MAXN],w1[MAXN][MAXN];
    int a[MAXN];
    int dp[MAXM][MAXN];
    pair<int,int> srange[MAXN];
    int stack[MAXN];
    int tops=-1;
    
    int main()
    {
            freopen("input.txt","r",stdin);
            int n,m;
            int x,y,z;
            scanf("%d%d",&n,&m);
            for (int i=1;i<=n;i++)
                    scanf("%d",a+i);
            for (int i=1;i<=n;i++)
            {
                    for (int j=i;j<=n;j++)
                    {
                            if ((i+j)/2==(i+j-1)/2)
                                    w[i][j]=w[i][j-1]+a[j]-a[(i+j)/2];
                            else
                                    w[i][j]=w[i][j-1]+(a[(i+j)/2]-a[(i+j-1)/2])*(((i+j)/2-i) - (j-(i+j)/2))
                                            +a[j]-a[(i+j)/2];
                    }
            }
            memset(dp,INF,sizeof(dp));
            dp[0][0]=0;
            srange[++tops]=make_pair(1,n);
            stack[tops]=0;
            for (int i=1;i<=m;i++)
            {
                    while (~tops)
                    {
                            for (int j=srange[tops].first;j<=srange[tops].second;j++)
                                    dp[i][j]=dp[i-1][stack[tops]]+w[stack[tops]+1][j];
                            tops--;
                    }
                    for (int j=1;j<=n;j++)
                    {
                            while (~tops && dp[i][j]+w[j+1][srange[tops].first]<dp[i][stack[tops]]+w[stack[tops]+1][srange[tops].first])
                                    tops--;
                            if (~tops)
                            {
                                    int l=srange[tops].first;
                                    int r=srange[tops].second+1;
                                    while (l+1<r)
                                    {
                                            int mid=(l+r)>>1;
                                            if (dp[i][j]+w[j+1][mid]<dp[i][stack[tops]]+w[stack[tops]+1][mid])
                                                    r=mid;
                                            else
                                                    l=mid;
                                    }
                                    srange[tops].second=l;
                                    if (r<=n)
                                    {
                                            srange[++tops]=make_pair(r,n);
                                    stack[tops]=j;
                                    }
                            }else
                            {
                                    srange[++tops]=make_pair(1,n);
                                    stack[tops]=j;
                            }
                    }
            }
            int ans=dp[m][n];
            printf("%d
    ",ans);
            return 0;
    }
    1D1D优化
    //bzoj 1856
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define MOD 20100403
    #define MAXN 2001000
    typedef long long qword;
    qword fact[MAXN];
    qword pow_mod(qword x,qword y)
    {
            qword ret=1;
            while (y)
            {
                    if (y&1)ret=ret*x%MOD;
                    x=x*x%MOD;
                    y>>=1;
            }
            return ret;
    }
    qword C(int x,int y)
    {
            if (x<y)return 0;
            return fact[x]*pow_mod(fact[x-y],MOD-2)%MOD*pow_mod(fact[y],MOD-2)%MOD;
    }
    
    int main()
    {
            //freopen("input.txt","r",stdin);
            int n,m;
            scanf("%d%d",&n,&m);
            fact[0]=1;
            for (int i=1;i<=n+m;i++)
                    fact[i]=fact[i-1]*i%MOD;
            qword ans=C(n+m,n)-C(n+m,n+1);
            ans=(ans%MOD+MOD)%MOD;
            printf("%d
    ",(int)ans);
    }
    Catalan
    Tarjan-缩点
    Tarjan-边双&&非递归
    Tarjan-点双
    整体二分
    //bzoj 3339
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<set>
    using namespace std;
    #define MAXN 210000
    #define smid ((l+r)>>1)
    int n,m;
    int a[MAXN];
    int tmp[MAXN],prv[MAXN];
    const int big=200000;
    struct qur_t
    {
            int id,l,r,ans;
    }qur[MAXN];
    vector<qur_t> vec;
    bool cmp_r(qur_t q1,qur_t q2)
    {
            return q1.r<q2.r;
    }
    int res[MAXN];
    void solve(int l,int r,vector<qur_t> &vec)
    {
            if (l==r)
            {
                    for (int i=0;i<vec.size();i++)
                            res[vec[i].id]=l;
                    return ;
            }
            vector<qur_t> v1,v2;
            multiset<int> S;
            sort(vec.begin(),vec.end(),cmp_r);
            for (int i=l;i<=smid;i++)
                    S.insert(tmp[i]);
            int cur=n;
            for (int i=vec.size()-1;i>=0;i--)
            {
                    while (vec[i].r<cur)
                    {
                            if (a[cur]<=smid && a[cur]>=l)
                            {
                                    S.erase(S.find(cur));
                                    S.insert(prv[cur]);
                            }
                            cur--;
                    }
                    if (*S.begin()<vec[i].l)
                            v1.push_back(vec[i]);
                    else
                            v2.push_back(vec[i]);
            }
            solve(l,smid,v1);
            solve(smid+1,r,v2);
    }
    
    int main()
    {
            freopen("input.txt","r",stdin);
            freopen("output.txt","w",stdout);
            int x,y,z;
            scanf("%d%d",&n,&m);
            for (int i=1;i<=n;i++)
                    scanf("%d",&a[i]);
            for (int i=1;i<=n;i++)
            {
                    prv[i]=tmp[a[i]];
                    tmp[a[i]]=i;
            }
            for (int i=1;i<=m;i++)
            {
                    scanf("%d%d",&qur[i].l,&qur[i].r);
                    qur[i].id=i;
            }
            vec.insert(vec.begin(),qur+1,qur+m+1);
            solve(0,big+1,vec);
            for (int i=1;i<=m;i++)
                    printf("%d
    ",res[i]);
    
    }
    SBT && 动态凸包

     

  • 相关阅读:
    CentOS 7 如何设置默认启动方式为命令行模式
    Virtual Box配置CentOS7网络
    序列化后成对象转map,再添加到dataList
    centos7 ping: www.baidu.com: Name or service not known
    协议1
    idea查看接口方法实现
    centos关闭防火墙
    myeclipse配置svn
    eas固定ip避免多次申请许可
    jvm配置
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4616949.html
Copyright © 2020-2023  润新知