2017西安网络赛 E. Maximum Flow F. Trig Function 组合数

来源:互联网 发布:同花顺手机炒股软件wp 编辑:程序博客网 时间:2024/06/05 06:37

 E. Maximum Flow

https://nanti.jisuanke.com/t/17118

从0到n-1,n个点,权值为点标号,每个点都有 向标号大于自己的点有一条有向边,边权为两结点权值异或值

求从0到n-1的最大流量


找到规律是结果为sum(max(i,i^(n-1))(i=1->n-1)

然后就可以根据数位来求这个结果了

#include<bits/stdc++.h>using namespace std;const int mo=1e9+7;long long a[100];int main(){long long n,i,j;    while(~scanf("%lld",&n))    {        n--;        long long ans=n;        long long temp=n;        int i=0;        while(temp)        {            a[i++]=temp&1;            temp>>=1;        }        temp=(1ll<<(i-1))-1;        n-=temp+1;        if(temp&1)            ans=(ans+((temp+1)/2)%mo*(temp%mo)%mo)%mo;        else            ans=(ans+(temp/2)%mo*((temp+1)%mo)%mo)%mo;        i--;        long long now=0;        for(j=i-1;j>=0;j--)        {           long long t1=(1ll<<j)%mo;            long long t2=now*t1%mo;            if(a[j])            {                ans=(ans+(t2+t1)*t1%mo)%mo;            }            else            {                ans=(ans+t2*t1%mo)%mo;            }            now<<=1;            now+=a[j];        }        printf("%lld\n",ans);    }    return 0;}

 F. Trig Function

https://nanti.jisuanke.com/t/17119

题意很简单

做法,套一个倍角公式


sin^2=1-cos^2

带进去,后面一项换为一个二项式:(1-cos^2)^ i 二项式展开,显然我们只需要求的是其中某一项的系数

令k=(m-(n-2*i))/2

我们需要的那个二项式的系数也就是C(i , k) * (-1) ^ k 


大组合数,lucas定理求,但复杂度似乎并不够

其实仔细看看公式,组合数可以依次递推出来,当时卡了半天,没脑子。。。

#include<bits/stdc++.h>using namespace std;typedef long long  ll;const int mo=998244353;const long long N=998244353;ll qpow(ll a,ll k){ll ans=1;while(k){if(k&1)ans=(ans*a)%mo;a=(a*a)%mo;k>>=1; }return ans; } ll C(ll a,ll b){if(a<b)return 0;if(b>a-b)b=a-b;ll up=1,down=1;for(ll i=0;i<b;i++){up=up*(a-i)%mo;down=down*(i+1)%mo;}return up*qpow(down,mo-2)%mo;}long long inv[6005000],fac[6005000];void init()  {      inv[0] = fac[0] = inv[1] = fac[1] = 1;      for(int i = 1; i < 6000000+10; i++)      fac[i] = fac[i - 1] * i % N;      for(int i = 2; i < 6000000+10; i++)      inv[i] = (N - (N / i)) * inv[N % i] % N;//lucas?????      for(int i = 1; i < 6000000+10; i++)      inv[i] = inv[i - 1] * inv[i] % N;   }   ll Comb(int n, int m)//???? C n,m   {      return (fac[n] * inv[m] % N) * inv[n - m] %N;   }  ll lucas(ll a,ll b){if(a<b||a<0||b<0)return 0;if(b==0)return 1;if(a<=6000000)return Comb(a,b);return C(a%mo,b%mo)*lucas(a/mo,b/mo)%mo; }int main(){int n,m,i;init();while(~scanf("%d %d",&n,&m)){if(((n-m)&1)||n<m)printf("0\n");else{long long ans=0;int i=(n-m)/2;int k=(m-n+2*i)/2;long long temp2=lucas(n,2*i);long long temp3=lucas(i,k);for(;2*i<=n;i++,k++){//cout<<i<<" "<<k<<endl;ans=(ans+temp2*temp3%mo*((k&1)?-1:1)*((i&1)?-1:1)+mo)%mo;temp3=(temp3+temp3*(i-k)%mo*qpow(k+1,mo-2))%mo;temp2=(temp2*(n-2*i)%mo*(n-2*i-1)%mo*qpow(2*i+1,mo-2)%mo*qpow(2*i+2,mo-2))%mo;}printf("%lld\n",ans);}}return 0;}


阅读全文
0 0
原创粉丝点击