zoukankan      html  css  js  c++  java
  • CCPC Wannafly Camp Day1C染色图

    题:https://ac.nowcoder.com/acm/contest/3979/C

    题意:给定一个函数g(n,k),指的是n个点的图,每个点可染k种颜色中的一种,只有不同颜色之间才可以进行连边,求能达到的最大连边数。题目要求的是Σg(n,i)

    分析:考虑单单的一个点k,考虑答案:C2n-p(总体-不满足=答案),而p函数显然就是相同颜色之间可连的边的数目,为了答案尽可能大,我们要让p函数尽可能小,即让相同颜色的点数的个数尽可能接近;

       具体地就是n%k种颜色染了n/k个点,k-n%k种颜色染了n/k+1个点。

       此时g(n,k)=C2n-(n%k)*Cx+12-(k-n%k)*Cx2   (其中x=n/k)

       将n%k==n-n/k*k带入得g(n,k)=n2-n-2nx+k(x2+x)

       而求和就考虑用分块解决(因为有x=n/k)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pb push_back
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    const int M=5e4+4;
    const int mod=998244353;
    ll ksm(ll a,ll b){
        ll t=1;
        while(b){
            if(b&1)
                t=(t*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return t;
    }
    ll solve(ll x,ll y,ll n){
        ll ans=0;
        ll l=x,r;
        while(l<=y){
         ///   cout<<l<<endl;
            r=n/(n/l);
            if(r>y)
                r=y;
            ll t=n/l;
            ans+=(n*n%mod-n-2*n%mod*t)%mod*(r-l+1)%mod;
            ans%=mod;
                                    ///等差求和///
            ans+=(((t*t%mod+t)%mod)*((r+l)*(r-l+1)/2)%mod)%mod;
            ans%=mod;
            l=r+1;
        }
        return ans;
    }
    int main(){
        int t;
        scanf("%d",&t);
        ll inv=ksm(2ll,mod-2);
        while(t--){
            ll l,r,n;
            scanf("%lld%lld%lld",&n,&l,&r);
            ll ans=solve(l,r,n);
            ans=(ans+mod)%mod;
            ans*=inv;
            printf("%lld
    ",ans%mod);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Markdown学习
    二叉树的最近公共祖先
    javaCompiler简析
    自定义类加载器
    聚合和组合的区别
    拓扑排序
    C++ map和unordered_map
    静态文件加载路径
    文件上传
    jackson
  • 原文地址:https://www.cnblogs.com/starve/p/12830687.html
Copyright © 2011-2022 走看看