zoukankan      html  css  js  c++  java
  • AT2364 Colorful Balls

    AT2364 Colorful Balls

    题意翻译

    N个球排成一排,第i个球有颜色ci和重量wi。 Snuke每次可以选择两个颜色相同,且重量之和不超过X的球,交换他们的位置。 Snuke每次可以选择两个颜色不同,且重量之和不超过Y的球,交换他们的位置。 问,可以得到多少种不同的颜色序列? 答案取膜1000000007

    输入输出样例

    输入样例#1: 
    4 7 3
    3 2
    4 3
    2 1
    4 4
    输出样例#1: 
    2
    输入样例#2: 
    1 1 1
    1 1
    输出样例#2: 
    1
    输入样例#3: 
    21 77 68
    16 73
    16 99
    19 66
    2 87
    2 16
    7 17
    10 36
    10 68
    2 38
    10 74
    13 55
    21 21
    3 7
    12 41
    13 88
    18 6
    2 12
    13 87
    1 9
    2 27
    13 15
    输出样例#3: 
    129729600

    sol:较容易的,可以发现如果a和b可以交换,b和c可以交换,那么a和c一定可以交换。

    于是可以缩成一个个连通块,把每个连通块中的方案数乘起来就是答案了。对于每个块,令块大小为B,每种颜色的个数分别为b1,b2,b3,...bn,那么答案就是B! / b1! / b2! / ... / bn!

    实现恶心的一匹,我用了并查集(应该可以用别的)码量感觉挺大的,但是有些人打的超短,不知道为什么qaq(我太菜菜菜菜菜菜菜菜菜菜菜菜菜了)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');    return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const ll Mod=1000000007;
    const int N=200005;
    int n,A,B;
    ll Jiec[N];
    int Father[N];
    int Min[N],CMin[N];
    int Cnt[N];
    struct Record
    {
        int Cor,W,Id;
    }Xins[N];
    inline int Get_Father(int x)
    {
        return (Father[x]==x)?(x):(Father[x]=Get_Father(Father[x]));
    }
    inline void Merge(int x,int y)
    {
        Father[Get_Father(x)]=Get_Father(y);
    }
    vector<int>Liantong[N];
    inline ll Ksm(ll x,ll y)
    {
        ll ans=1;
        while(y)
        {
            if(y&1) ans=ans*x%Mod;
            x=x*x%Mod;
            y>>=1;
        }
        return ans;
    }
    int main()
    {
        int i,j;
        R(n); R(A); R(B);
        Jiec[0]=1; for(i=1;i<=n;i++) Jiec[i]=1ll*Jiec[i-1]*i%Mod;
        Xins[0].W=0x3f3f3f3f;
        for(i=1;i<=n;i++)
        {
            Father[i]=i;
            R(Xins[i].Cor); R(Xins[i].W); Xins[i].Id=i;
            if(Xins[i].W<=Xins[Min[Xins[i].Cor]].W)
            {
                CMin[Xins[i].Cor]=Min[Xins[i].Cor];
                Min[Xins[i].Cor]=i;
            }
            else if(Xins[i].W<Xins[CMin[Xins[i].Cor]].W)
            {
                CMin[Xins[i].Cor]=i;
            }
        }
        int Fir=0,Sec=0;
        for(i=1;i<=n;i++)
        {
            if(Fir==0||Xins[i].W<Xins[Min[Fir]].W) {Sec=Fir; Fir=Xins[i].Cor;}
            else if(Sec==0||Xins[i].W<Xins[Min[Sec]].W) Sec=Xins[i].Cor;
        }
        for(i=1;i<=n;i++)
        {
            if(Xins[i].W+Xins[Min[Xins[i].Cor]].W<=A)
            {
                if(i!=Min[Xins[i].Cor]) Merge(i,Min[Xins[i].Cor]);
            }
            if(Xins[i].Cor==Fir)
            {
                if(Xins[i].W+Xins[Min[Sec]].W<=B) Merge(i,Min[Sec]);
            }
            else
            {
                if(Xins[i].W+Xins[Min[Fir]].W<=B) Merge(i,Min[Fir]);
            }
        }
        for(i=1;i<=n;i++) Liantong[Get_Father(i)].push_back(i);
    //    for(i=1;i<=n;i++) if(Liantong[i].size())
    //    {
    //        for(j=0;j<Liantong[i].size();j++) W(Liantong[i][j]);
    //        puts("");
    //    }
        ll ans=1;
        for(i=1;i<=n;i++) if(Liantong[i].size())
        {
            for(j=0;j<Liantong[i].size();j++)
            {
                Cnt[Xins[Liantong[i][j]].Cor]++;
            }
            ll tmp=Jiec[Liantong[i].size()];
            for(j=0;j<Liantong[i].size();j++) if(Cnt[Xins[Liantong[i][j]].Cor])
            {
                tmp=1ll*tmp*Ksm(Jiec[Cnt[Xins[Liantong[i][j]].Cor]],Mod-2)%Mod;
                Cnt[Xins[Liantong[i][j]].Cor]=0;
            }
            ans=1ll*ans*tmp%Mod;
        }
        Wl(ans);
        return 0;
    }
    /*
    input
    4 7 3
    3 2
    4 3
    2 1
    4 4
    output
    2
    
    input
    5 99 100
    5 91
    2 42
    3 63
    3 35
    4 21
    output
    12
    
    input
    21 77 68
    16 73
    16 99
    19 66
    2 87
    2 16
    7 17
    10 36
    10 68
    2 38
    10 74
    13 55
    21 21
    3 7
    12 41
    13 88
    18 6
    2 12
    13 87
    1 9
    2 27
    13 15
    output
    129729600
    */
    View Code
  • 相关阅读:
    Flask、Vue部署总结
    Recat教程(二)
    C第一个程序
    React教程(一)
    Flask+uwsgi+nginx 部署
    使用Dockerfile部署简单的应用
    Typescript搭建开发环境
    Typescript模块化/命名空间/装饰器
    Typescript的泛型/泛型接口
    修改git密码后,终端fatal: Authentication failed for'http://xxx/xxx.git'
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10629259.html
Copyright © 2011-2022 走看看