• bzoj5407: girls


    题目描述:

    大皮出行,妹子成群,似乎这种事早已经司空见惯了。 大皮最终还是厌倦了这样的⽣活,懂得了节制,他希望每次恰好只有三个妹子陪他。

     大皮有 $n$个妹子,编号为$0$到$n-1$ ,大皮需要次从$n$个中选出三个来愉悦身心。

    那么问题来了,有许多妹子为了得到大皮的欢心,产生了冲突,这样的冲突一共有$m$组,为了让自己的出行能清净些,大皮不希望选出的三个妹子,有任何一对存在冲突。

    对于每一次选择的三个妹子$i,j,k(i<j<k)$,大皮可以得到的愉悦值为

    $A imes i+B imes j+C imes k$

    大皮希望你帮他求出所有方案可以得到的愉悦值之和,由于答案太大,请输出答案$mod 2^{64}$

    算法标签:三元环计数,容斥

    思路:

    对于满足的方案容斥一下。

    所有方案-有一条边的+有两条边的-有三条边的

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define ull unsigned long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=2e5+5;
    bool vis[N];
    ull A,B,C,ans;
    int n,m,q[4],in[N];
    struct node{
        int l,r;
    }t[N];
    vector<int> v[N];
    il int read(){
        int x,f=1;char ch;
        _(!)ch=='-'?f=-1:f;x=ch^48;
        _()x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    int main()
    {
        n=read();m=read();
        scanf("%llu%llu%llu",&A,&B,&C);
        for(int i=1;i<=n;i++){
            if(i<n-1)ans+=A*(ull)(1ll*(n-i)*(n-i-1)/2)*(i-1);
            if(i!=1&&i!=n)ans+=B*(ull)(1ll*(i-1)*(n-i))*(i-1);
            if(i>2)ans+=C*(ull)(1ll*(i-1)*(i-2)/2)*(i-1);
        }
        for(int i=1;i<=m;i++){
            int x=read()+1,y=read()+1;
            in[x]++;in[y]++;
            t[i]=(node){x,y};
            if(x>y)swap(x,y);
            ans-=(ull)(B*(x-1)+C*(y-1))*(ull)(x-1)+A*(ull)(1ll*(x-1)*(x-2)/2ll);
            ans-=(ull)(A*(x-1)+C*(y-1))*(ull)(y-x-1)+B*(ull)(1ll*(y-x-1)*(x+y-2)/2ll);
            ans-=(ull)(A*(x-1)+B*(y-1))*(ull)(n-y)+C*(ull)(1ll*(n-y)*(y-1+n)/2ll);
            v[x].push_back(y);v[y].push_back(x);
        }
        for(int i=1;i<=n;i++)sort(v[i].begin(),v[i].end());
        for(int x=1;x<=n;x++){
            int sz=v[x].size()-1;
            int num1=0,num2=0;
            for(int i=0;i<=sz;i++){
                int to=v[x][i];
                if(to<x){
                    num1++;
                    ans+=A*(to-1)*(sz-i)+B*(to-1)*i;
                }
                else{
                    num2++;
                    ans+=B*(to-1)*(sz-i)+C*(to-1)*i;
                }
            }
            ans+=(ull)(x-1)*(A*(1ll*num2*(num2-1)/2)+B*(1ll*num1*num2)+C*(1ll*num1*(num1-1)/2));
        }
        for(int i=1;i<=n;i++)v[i].clear();
        for(int i=1;i<=m;i++){
            int x=t[i].l,y=t[i].r;
            if(in[x]<in[y]||(in[x]==in[y]&&x>y))swap(x,y);
            v[x].push_back(y);
        }
        for(int x=1;x<=n;x++){
            for(int i=0;i<v[x].size();i++)vis[v[x][i]]=1;
            for(int i=0;i<v[x].size();i++){
                int to=v[x][i];
                for(int j=0;j<v[to].size();j++){
                    if(vis[v[to][j]]){
                        q[1]=x-1;q[2]=to-1;q[3]=v[to][j]-1;
                        sort(q+1,q+4);
                        ans-=A*q[1]+B*q[2]+C*q[3];
                    }
                }
            }
            for(int i=0;i<v[x].size();i++)vis[v[x][i]]=0;
        }
        printf("%llu
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Java 学习 第二篇;面向对象 定义类的简单语法:
    Java 学习 第一篇
    Compiler Principles 语法分析
    未来智能机的发展趋势
    C语言IO操作总结
    python学习资料
    JavaScript 数组的创建
    JavaScript中的逗号运算符
    JavaScript本地对象 内置对象 宿主对象
    JavaScript的this用法
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10427874.html
Copyright © 2020-2023  润新知