zoukankan      html  css  js  c++  java
  • 长春

    长春

    B-Fraction

    tag:签到题

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+100;
    ll a[maxn],b[maxn];
    int main()
    {
        int T;scanf("%d",&T);int t=0;
        while(T--)
        {
            int n;scanf("%d",&n);
            for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
            for(int i=1;i<=n;i++)scanf("%lld",&b[i]);
            ll p=b[n],q=a[n],temp,temq;
            for(int i=n-1;i>=1;i--)
            {
                temp=b[i]*q,temq=a[i]*q+p;
                swap(p,temp),swap(temq,q);
            }
            ll g=__gcd(p,q);
            printf("Case #%d: %lld %lld\n",++t,p/g,q/g);
    
        }
    }
    
    
    G-Instability

    题意:给定一张无向图n<51,问其中包含qaq[三个点两两不相连或者三个点两两相连]的集合数

    注意点:1.敲一个组合数表不然可能会tle

    题解:算是结论题Ramsey定理。

    结论:六个点及以上的集合必然包含qaq;

    证明:连边为红,不连边为蓝

    由鸽巢定理得,\(\forall a\in s, 与它相连的5条边至少有三条同色,假设为红。这三条边都蓝色,就构成蓝色三角形,存在红色,就有红色三角形\)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define debug(x) cout<<#x<<':'<<x<<endl;
    const int mod=1e9+7;
    int d[100][100],c[100][100];
    bool check(int i ,int j,int k){return d[i][j]==d[j][k]&&d[j][k]==d[k][i];}
    int main()
    {
        ll T,n,m,u,v;
        scanf("%lld",&T);int t=0;
        for(int i=0;i<51;i++)//组合数
            c[i][0]=c[i][i]=1;
        for(int i=2;i<51;i++) {
            for (int j = 1; j < i; j++)
                c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
        }
        while(T--)
        {
            scanf("%lld%lld",&n,&m);
            memset(d,0,sizeof(d));
            ll ans=0;
            while(m--)
            {
                scanf("%lld%lld",&u,&v);d[u][v]=d[v][u]=1;
            }
            if(n>=6)
                for(int w=6;w<=n;w++)
                    ans=(ans+c[n][w])%mod;
            if(n>=5)
            {
                for(int i=1;i<=n;i++)
                    for(int j=i+1;j<=n;j++)
                        for(int k=j+1;k<=n;k++)
                            for(int q=k+1;q<=n;q++)
                                for(int p=q+1;p<=n;p++)
                                if(check(i,j,k)||check(i,j,q)||check(i,k,q)||check(j,k,q)||check(i,j,p)||check(i,k,p)||check(i,q,p)||check(j,k,p)||check(j,q,p)||check(k,p,q)) ans++;
            }
            ans%=mod;
            if(n>=4)
            {
                for(int i=1;i<=n;i++)
                    for(int j=i+1;j<=n;j++)
                        for(int k=j+1;k<=n;k++)
                            for(int q=k+1;q<=n;q++)
                                if(check(i,j,k)||check(i,j,q)||check(i,k,q)||check(j,k,q)) ans++;
            }
            ans%=mod;
            if(n>=3)
            {
                for(int i=1;i<=n;i++)
                    for(int j=i+1;j<=n;j++)
                        for(int k=j+1;k<=n;k++)
                            if(check(i,j,k)) ans++;
            }
            printf("Case #%d: %lld\n",++t,ans%mod);
        }
    }
    

    K- Binary Indexed Tree

    image-20201112183428762

    题意:求:\(ans=\sum_{i=0}^{n}g(i)+\sum_{i=0}^n\sum_{j=0}^nlcp(g(i,j))\),g(i)表示i转二进制后1的数量。

    ​ 如图,连线表示相差一个lowbit,在进行一次操作的时候,0-4这段被抵消了,于是可以转换题意如上

    题解:对于每一位i(i从1开始),pow2[i]一组,组数记为tuan,除组数以外的1的数量记为san

    ​ 以第三位为例,可以分成tuan=1,san=0;第四位tuan=0,san=1;

    ​ 为了把0算作一个数,所以n++,n表示从0开始的数字的数量

    ​ tuan=n/pow2[i],san=(n%pow2[i]/pow2[i-1])*(n%pow2[i-1])

    ​ 遍历每一位的时候,

    ​ ansleft+=n·(tuan·pow2[i-1]+san)//把该位是1的个数加上

    ​ ansright+=tuan·pow2[i-1]·pow2[i-1]+san·san//因为对于每一组它们的lcp都包括该位

    pow2[i]: 32 16 8 4 2 1

    num=0 0 0 0 0 0 0

    num=1 0 0 0 0 0 1

    num=2 0 0 0 0 1 0

    num=3 0 0 0 0 1 1

    num=4 0 0 0 1 0 0

    num=5 0 0 0 1 0 1

    num=6 0 0 0 1 1 0

    num=7 0 0 0 1 1 1

    num=8 0 0 1 0 0 0

    注意点:我都怀疑这题是在考大数,几乎每一个数都要加%mod,我写了一遍python[python不给交,以及注意python:mod=int(1e9+7),要转int]确认思路没问题了才继续改c++

    python:

    pow2=[1,]
    t=1;
    mod=int(1e9+7)
    for i in range(1,64):
    	t*=2
    	pow2.append(int(t))
    T=int (input())
    for t in range(1,T+1):
    	n=int (input())
    	ansleft=int(0)
    	ansright=int(0)
    	n+=1
    	for i in range(63,0,-1):
    		san=int(((n%pow2[i])//pow2[i-1])*(n%pow2[i-1]))
    		tuan=int(n//pow2[i])
    		ansright+=int(tuan*pow2[i-1]*pow2[i-1]+san*san)
    		ansleft+=int(n*(tuan*pow2[i-1]+san))
    	print("Case #",end="")
    	print(t,end="")
    	print(": ",end="")
    	print(int((ansleft%mod+mod-ansright%mod)%mod))
    

    c++

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    #define debug(x) cout<<#x<<':'<<x<<endl;
    const int mod=1e9+7;
    ull pow2[65];
    ull mul(ull a,ull b){a%=mod,b%=mod;return a*b%mod;}
    int main()
    {
        pow2[0]=1;
        for(int i=1;i<64;i++)pow2[i]=pow2[i-1]*2;
        int T,t=0;scanf("%d",&T);
        while(T--)
        {
            ull n;scanf("%llu",&n);n++;//n为算上零后的个数,
            ull ansleft=0,ansright=0;
            for(int i=63;i>=1;i--)
            {
                ull san=mul((n%pow2[i])/pow2[i-1],n%pow2[i-1]);
                ull tuan=(n/pow2[i])%mod;
                 ansright=(ansright+mul(tuan,mul(pow2[i-1],pow2[i-1]))+mul(san,san))%mod;
               // ansright=((ansright+(((tuan*(pow2[i-1]%mod))%mod)*(pow2[i-1]%mod))%mod+(san*san)%mod)%mod)%mod;
                ansleft=(ansleft+mul(n,mul(tuan,pow2[i-1])+san))%mod;
               //ansleft=(ansleft+(n%mod)*(tuan*pow2[i-1]%mod+san))%mod;
            }
            printf("Case #%d: %lld\n",++t,(ansleft+mod-ansright)%mod);
    
        }
    }
    
  • 相关阅读:
    Android license status unknown,亲测有效
    android studio 如何升级sdk
    Java就业前景如何?前途&钱途?如何成为Java工程师?
    Java程序的编写与执行、Java新手常见的问题解决
    学习java需要掌握什么基础?如何学
    Java8中你可能不知道的一些地方之Optional实战
    P1407 [国家集训队]稳定婚姻
    P5960 【模板】差分约束算法
    P3388 【模板】割点(割顶)
    2020.8.4
  • 原文地址:https://www.cnblogs.com/zx0710/p/13965776.html
Copyright © 2011-2022 走看看