Full_of_Boys训练6总结

题目来源:2014-2015 ACM-ICPC, Asia Xian Regional Contest

F. Color

第一道二项式反演。。膜题解: https://www.cnblogs.com/wmrv587/p/6681953.html

#include<bits/stdc++.h>
typedef long long ll;
const ll mod = 1e9 + 7;
using namespace std;
ll q_pow(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
ll n,m,k,inv[1000007];
ll C(ll n,ll m){ll t=1;
    for(ll i=n-m+1;i<=n;++i)t=(t*i)%mod;
    for(ll i=1;i<=m;++i)t=(t*inv[i])%mod;
    return t;
}
ll a(ll x){return ((x%mod)*q_pow(x-1,n-1)%mod)%mod;}
int T,K;
int main() {
    scanf("%d",&T);
    for(int i=1;i<=1e6;++i)inv[i]=q_pow(i,mod-2);
    while(T--){
        scanf("%lld%lld%lld",&n,&m,&k);
        ll ans=0,w=1,Cki=1;if(k%2)w=-1;
        for(int i=0;i<=k;++i,w=-w){
            ans = (ans%mod + (w*(Cki%mod*a(i)%mod)%mod+mod)%mod)%mod;
            Cki=(((Cki%mod)*(k-i)%mod)*inv[i+1]%mod)%mod;
        }
        ans = (ans*C(m,k))%mod;
        printf("Case #%d: %lld\n",++K,ans);
    }
}

C. The Problem Needs 3D Arrays

将有逆序关系的点相连,题目转化为,求最大密度子图。回去复习论文。。

update:今天看了一下,马上就想起来了。。。于是写了一下。。。有点伤感。。。按论文第一种方式建二分图。。。T了?,,于是学了第二种建图。。。精度炸了?倒查了3个小时。。。inf开大了,导致大数,吞小数。。。计方老师。。。终于过了第一个样例。。。T在第二个?查了半小时。。。数组开太大了,还用的memset。。。,改掉成WA了?于是把eps调小了点。。。当我准备改long double时。过了。。。真的是好感伤。。。就读过几篇论文。。。被考到了。。。还不会。。。知道了还写炸。。。没救了。没救了。

#include <bits/stdc++.h>
#define pb(x) push_back(x)
#define LD long double
typedef long long ll;
const int maxn = 510000;
const int maxm = 2100000;
const double eps = 1e-7;
using namespace std;
double inf;
int T,n,a[111];
struct node{
    int x,y;
    node(){}
    node(int a,int b){x=a;y=b;}
};
vector<node> ee;
struct edge{int e,nxt;LD w;}E[maxm];
int h[maxn],cc;
void add(int u,int v,LD w){
    E[cc].e=v;E[cc].w=w;E[cc].nxt=h[u];h[u]=cc;++cc;
    E[cc].e=u;E[cc].w=0;E[cc].nxt=h[v];h[v]=cc;++cc;
}
int dd[maxn],q[maxn],st,ed;
int bfs(){
    int l=0,r=0;for(int i=0;i<=n+1;++i)dd[i]=0;
    q[r]=st;++r;dd[st]=1;
    while(l<r){
        int u=q[l];++l;
        for(int i=h[u];~i;i=E[i].nxt){
            int v=E[i].e;
            if(!dd[v]&&E[i].w>=eps){
                dd[v]=dd[u]+1;
                q[r]=v;++r;
                if(v==ed)return 1;
            }
        }
    }
    return 0;
}
LD dfs(int u,LD fl) {
    if(u==ed)return fl;
    LD s=fl,t;
    for(int i=h[u];~i;i=E[i].nxt){
        int v=E[i].e;
        if(dd[v]==dd[u]+1&&E[i].w>=eps&&s>=eps){
            t=dfs(v,min(E[i].w,s));
            s-=t;
            E[i].w-=t;E[i^1].w+=t;
            if(s<eps)return fl;
        }
    }
    if(abs(s-fl)<eps) dd[u]=0;
    return fl-s;
}
LD dinic(){
    LD ans=0;
    while(bfs())ans+=dfs(st,inf);
    return ans;
}
int m,d[111];
void build(LD  g){
    for(int i=0;i<=n+1;++i)h[i]=-1;cc=0;
    st=0;ed=n+1;inf=m*3+m*n+m+2*g+10000.0;
    for(int i=0;i<m;++i){
        add(ee[i].x,ee[i].y,1.0);
        add(ee[i].y,ee[i].x,1.0);
    }
    for(int i=1;i<=n;++i){
        add(st,i,m*1.0);
        add(i,ed,m*1.0+2.0*g-d[i]);
    }
}
LD  solve(LD  g) {
    build(g);
    return (n*m*1.0-dinic());
}
int K=0;
int main() {
    scanf("%d",&T);
    while(T--) {ee.clear();
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%d",&a[i]),d[i]=0;
        for(int i=2;i<=n;++i)
            for(int j=1;j<i;++j)if(a[j]>a[i]){
                ee.pb(node(i,j));
                ++d[i];++d[j];
            }
        m=ee.size();
        LD  l=0, r = m, mid;
        int tt=0;
        while(r-l>=eps){
            mid = (l+r)/2.0; LD t = solve(mid);
            //printf("%f %f\n",(double)mid,(double)t);
            if(t>eps)l=mid;
            else r=mid;
        }
        printf("Case #%d: %f\n",++K,(double)l);
    }
    return 0;
}
//5
//5
//3 4 2 5 1

  

posted @ 2018-05-16 23:35  RRRR_wys  阅读(388)  评论(0编辑  收藏  举报