zoukankan      html  css  js  c++  java
  • 11.7 NOIP模拟赛


    2018.11.7 NOIP模拟

    时间:3.5h
    期望得分:100+0+40
    实际得分:100+0+40

    A 序列sequence(two pointers)

    其实我们只要处理每个数与哪些数相加,会产生进位就行了。
    把数排序后,枚举一个数x,容易想到满足使x+y进位的y是单调的(要求y<=x)。所以可以二分。
    但是单调,好像只需要two pointers就可以了?但比如10 100 990 9900,好像不单调了(990与9900)?
    事实上只要对位数相同的算就可以了,即最多只算8段,这一段中数的位数相同,然后令l=1,向r移动;r=j,向i移动,对每个r计算答案就行了(i,j是有相同位数的数的这一段的左右端点)。
    复杂度(O(nlog n+n))

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 300000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    #define Count(x) (x>100000?bit[(x)/100000]+5:bit[x])
    typedef long long LL;
    const int N=1e6+5;
    
    int A[N],bit[100005],pw[233];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    
    int main()
    {
    	freopen("sequence.in","r",stdin);
    	freopen("sequence.out","w",stdout);
    
    	pw[0]=1;
    	for(int i=1; i<=9; ++i) pw[i]=pw[i-1]*10;
    	for(int i=1; i<=100000; ++i) bit[i]=bit[i/10]+1;
    	int n=read(); LL ans=0;
    	for(int i=1; i<=n; ++i) A[i]=read();
    	std::sort(A+1,A+1+n), A[n+1]=1e9;
    	for(int i=1,x,y,las=1; i<=n; ++i)
    	{
    		y=Count(A[i]), ans+=y*(i-1);
    		if(y!=Count(A[i+1]))
    		{
    			int l=1,r=i;
    			while(l<r && r>=las)
    			{
    				while(l<r && A[l]<pw[y]-A[r]) ++l;
    				ans+=r-l, --r;
    			}
    			las=i+1;
    		}
    	}
    	printf("%I64d
    ",ans);
    
    	return 0;
    }
    

    B 锁lock(思路)

    模拟一下样例,也就是我们知道了一共6个钥匙:
    首先对于1 2,他们合起来不能有所有钥匙,所以假设他们都没有钥匙1;
    同理对于1 3,假设他们都没有钥匙2...
    而如果2个人的情况满足了,1个人显然不能凑够6把钥匙。
    这样把所有(m-1)个人的组合都分配一遍,正好是6。所以在(A_i=1)时,答案应该是(C_n^{m-1})
    那么(A_i eq1)时呢?
    同理,对于极大的重要度不足(m)的一个集合(s),我们要令他们都没有某一个钥匙。然后对于(s)的所有子集都已经满足条件,之后就不需要枚举了。
    (2^n)枚举集合,判一下有多少极大的重要度不足(m)的集合,就知道要有多少个钥匙了。
    (极大的是指,该集合加入任意一个该集合外的元素,重要度都(geq m)。)

    复杂度(O(n*2^n))
    注意所有(Ai)的和不足(m)时输出(1),因为所有人也不能满足。

    mjtnb!mjtAKxxxP!

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    typedef long long LL;
    const int N=23;
    
    int A[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    
    int main()
    {
    	freopen("lock.in","r",stdin);
    	freopen("lock.out","w",stdout);
    
    	int n=read(),m=read(); LL s=0;
    	for(int i=0; i<n; ++i) s+=A[i]=read();
    	if(s<m) return printf("1
    "),0;
    	int ans=0;
    	for(int s=0,lim=1<<n; s<lim; ++s)
    	{
    		int sum=0,mn=1e9;
    		for(int i=0; i<n; ++i) s>>i&1?(sum+=A[i]):(mn=std::min(mn,A[i]));
    		ans+=(sum<m&&sum+mn>=m);
    	}
    	printf("%d
    ",ans);
    
    	return 0;
    }
    

    C 正方形square(埃氏筛)

    莫比乌斯反演推出50分做法了,想错复杂度没写,sad(好像没什么用)。
    忘掉欧拉函数了。




    最后一步没看懂,贴std:

    # include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int T=1e7, N=1e7 + 10, P=19260817;
    int sum[N], use[N], mul[N];
    int power(int x, int y){
        int i=x; x=1;
        while (y > 0){
            if (y%2 == 1) x=1ll*x*i%P;
            i=1ll*i*i%P;
            y /= 2;
        }
        return x;
    }
    void pre(){
        use[1]=true;
        for (int i=0; i<=T; i++) sum[i]=1;
        for (int i=2; i<=T; i++)
            if (use[i] == false){
                ll t=i;
                for (int k=1; t<=T; k++, t*=i){//t=i^k
                    for (int tmp=t, num=i; tmp<=T; tmp+=t, num=1ll*num*i%P*i%P)
                        sum[tmp]=1ll*sum[tmp]*num%P;
                }
                for (int k=i; k<=T; k+=i) use[k]=true;
            }
        for (int i=1; i<=T; i++) sum[i]=1ll*sum[i-1]*sum[i]%P;
        for (int i=1; i<=T; i++) sum[i]=1ll*sum[i]*sum[i]%P;
        mul[0]=1; for (int i=1; i<=T; i++) mul[i]=1ll*mul[i-1]*i%P;
    }
    int main(){
    	freopen("square.in","r",stdin);;
    	freopen("square.out","w",stdout);
        pre();
        std::ios::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);
        int opt;cin>>opt;
        while (opt--){
            int n;cin>>n;
            int tmp=R1ll*power(mul[n], 2*n)*power(sum[n], P-2)%P;
            cout<<tmp<<'
    ';
        }
        return 0;
    }
    

    考试代码

    B

    自闭。

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    typedef long long LL;
    const int N=23;
    
    int A[N];
    
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    
    int main()
    {
    	freopen("lock.in","r",stdin);
    	freopen("lock.out","w",stdout);
    
    	int n=read(),m=read();
    	for(int i=1; i<=n; ++i) A[i]=read();
    	if(n==4&&m==3) return printf("6"),0;
    	if(n==4&&m==2) return printf("4"),0;
    	if(n==3&&m==2) return printf("2"),0;
    	if(n==1||m==1) return printf("1"),0;
    	if(n==m) return printf("%d",n),0;
    	printf("%I64d
    ",1ll*(n-2)*m);
    
    	return 0;
    }
    

    C

    /*
    我好像只会
    O(Tn^2log)
    O(n^2+Tlog)
    O(nsqrt(n)+Tlog)
    所以这是什么奇怪的部分分。
    */
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 300000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    #define mod 19260817
    #define Inv(x) FP(x,mod-2)
    typedef long long LL;
    const int N=1e7+5;
    
    int fac[N],inv[mod+4],prod[N];
    char IN[MAXIN],*SS=IN,*TT=IN,OUT[10000000],*O=OUT;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline void Print(int x)
    {
    	static char sk[10];
    	int t=0;
    	while(x) sk[t++]=x%10+'0',x/=10;
    	while(t--) *O++=sk[t];
    	*O++='
    ';
    }
    inline int FP(int x,int k)
    {
    	int t=1;
    	for(; k; k>>=1,x=1ll*x*x%mod)
    		k&1&&(t=1ll*t*x%mod);
    	return t;
    }
    int Gcd(int x,int y)
    {
    	return y?Gcd(y,x%y):x;
    }
    
    int main()
    {
    	freopen("square.in","r",stdin);
    	freopen("square.out","w",stdout);
    
    	fac[0]=fac[1]=1, inv[1]=1;
    	for(int i=2; i<=10000001; ++i) fac[i]=1ll*fac[i-1]*i%mod;
    	for(int i=2; i<mod; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    	prod[1]=1;
    	for(int i=2; i<=1000; ++i)
    	{
    		LL tmp=prod[i-1];
    		for(int j=2,g; j<i; ++j) g=Gcd(i,j), g=inv[1ll*g*g%mod], tmp=tmp*g%mod*g%mod;
    		prod[i]=tmp*inv[1ll*i*i%mod]%mod;
    //		for(int j=2,g; j<i; ++j) g=Gcd(i,j), tmp=tmp*(g*g%mod);
    //		prod[i]=tmp*(i*i%mod)%mod;
    	}
    //	for(int i=1; i<=30; ++i) printf("prod[%d]=%d
    ",i,prod[i]);
    //	return 0;
    
    	for(int T=read(); T--; )
    	{
    		int n=read();
    		Print(1ll*FP(fac[n],n<<1)*prod[n]%mod);
    	}
    	fwrite(OUT,O-OUT,1,stdout);
    
    	return 0;
    }
    
  • 相关阅读:
    JavaScript入门基础(三)
    JavaScript入门基础(二)
    Web页面该如何布局
    如何通过SQL创建删除表的索引,UNIQUE KEY
    vim使用大全
    安装vmwaretools后 真机和虚拟机仍不能复制黏贴
    php通用函数html时间文件大小生成随机数
    Centos下安装配置phpmyadmin
    [Leetcode 43] 11 Container With Most Water
    [Leetcode 39] 129 Sum Root to Leaf Numbers
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9925706.html
Copyright © 2011-2022 走看看