其他分享
首页 > 其他分享> > 长春

长春

作者:互联网

长春

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);

    }
}

标签:tuan,san,pow2,int,num,长春,mod
来源: https://www.cnblogs.com/zx0710/p/13965776.html