zoukankan      html  css  js  c++  java
  • 牛客练习赛87 部分题题解

    k小数查询

    我就说题目描述中说到什么算法,就一定不会用到什么算法...果然在想清楚之前最好还是不要打代码,不然就是wrong,调,wrong,调...陷入死循环...考虑这个题,考虑x肯定是一个关键,先找到x的位置,那么左端点一定小于等于os(x的下标位置)。思考后发现小于x的数十分关键,并且我们要保证合法的区间中一定只有k-1个小于x的数。既然如此,我们就将所有小于x的数的下标放到一个数组里,枚举每个左端点,统计每个左端点对答案的贡献。对于每个左端点而言,首先必须保证右端点要大于等于os,其次这个区间里只能有k-1个比x小的数字。那我们直接在刚才存过的数组里面找当前k-1个数组的下标即可,并且可以直接根据下一个小于x的位置计算答案。....

    //不等,不问,不犹豫,不回头.
    #include<bits/stdc++.h>
    #define _ 0
    #define ls p<<1
    #define db double
    #define rs p<<1|1
    #define P 1000000007
    #define ll long long
    #define INF 1000000000
    #define get(x) x=read()
    #define PLI pair<ll,int>
    #define PII pair<int,int>
    #define ull unsigned long long
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define rep(x,y,z) for(int x=y;x<=z;++x)
    #define fep(x,y,z) for(int x=y;x>=z;--x)
    #define go(x) for(int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
    using namespace std;
    const int N=200010;
    int n,k,a[N],x,b[N],num;
    
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    
    int main()
    {
        //freopen("1.in","r",stdin);
    	get(n);get(x);get(k);
    	int os;
    	rep(i,1,n) 
    	{
    		get(a[i]);
    		if(a[i]==x) os=i;
    	}	
    	int sum=0;
    	rep(i,1,n)  
    	{
    		if(a[i]<x) 
    		{
    			b[++num]=i;
    			if(i<os) sum++;	
    		}	
    	}
    	b[num+1]=n+1;
    	ll ans=0; 
    	int dd=1;
    	rep(i,1,os)//枚举每一个左端点。
    	{
    		int ss=dd;//ss表示当前i这个点离得最近的小于x的下标在b中的下标。 
    		if(sum<=k-1&&ss+k-2<=num)
    		{
    			ans+=b[ss+k-1]-max(b[ss+k-2],os);
    		}
    		if(i==b[dd]) dd++,sum--;
    	} 
    	putl(ans);
        return (0^_^0);
    }
    //以吾之血,铸吾最后的亡魂.
    

    牛老板

    好吧,我承认是我失去了勇气,没有继续思考下去...
    考虑这个题,如果只用6和9的话,显然每个数都能转化成6进制数和9进制数,那么用的纸币的数量就是转化成的6进制数和9进制数下所有位数的和,考虑两个一起用的话,怎样会使答案更优,显然是某些数,在转化成9进制数时,其中某部分所有位数的和非常大,但用6进制的话就很简单了。如果这个不理解的话,可以这样想,每个数都可以写成若干个9的次幂相乘的形式,(当然了前面是有系数的但系数小于等于8),我们考虑如何用(6^i)使得答案更优,可能存在一些部分我们进行适当的拆解出来后,这一部分用(6^i)表示出来后系数和会更小,既然如此,我们直接考虑当前数的最高位的进制是9还是6,然后用递归的方式实现并且在两者之间取min即可。

    //不等,不问,不犹豫,不回头.
    #include<bits/stdc++.h> 
    #define _ 0
    #define ls p<<1
    #define db double
    #define rs p<<1|1
    #define P 1000000007
    #define ll long long
    #define INF 1000000000
    #define get(x) x=read()
    #define PLI pair<ll,int>
    #define PII pair<int,int>
    #define ull unsigned long long
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define rep(x,y,z) for(int x=y;x<=z;++x)
    #define fep(x,y,z) for(int x=y;x>=z;--x)
    #define go(x) for(int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
    using namespace std;
    map<ll,int>f;
    
    inline ll read()
    {
        ll x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    
    inline int find(ll n)
    {
    	if(n<6) return n;
    	if(f.find(n)!=f.end()) return f[n];
    	ll s1=1,s2=1;
    	while(s1*6<=n) s1*=6;
    	while(s2*9<=n) s2*=9;
    	return f[n]=min(find(n-s1),find(n-s2))+1;
    }
    
    int main()
    {
        //freopen("1.in","r",stdin);
    	int get(T);
    	while(T--)
    	{
    		ll get(n);
    		putl(find(n));
    	}
        return (0^_^0);
    }
    //以吾之血,铸吾最后的亡魂.
    
    

    贪吃蛇

    比遍体鳞伤更可怕的是内心的堕落....
    考虑最后牛牛蛇的最大长度是多少?肯定是全部蛇的和啊,只要让一个蛇吃掉其他全部的蛇就可以了。那我们的目标就是每一次都尽可能增加这个全部蛇的和,考虑怎么样才能达到这个目的,由于复活的时间是固定的,我们可以将时间T分为(frac{T}{x}+1)这么多轮,每一轮可以进行蛇吃蛇的操作,显然的是由于蛇复活的长度不变,所以我们每轮都让蛇吃别人或被吃,这样的话下一轮复活后总增加后的长度最大。考虑怎么做,我们可以先将所有蛇的长度从小到大排序,我们向让次大的吃最大的,第三大的吃次大的,第四大的吃第三大的,...这样一直进行下去,这样能使最大的长度不断累计...最后最小的吃次小的,这样一轮之后,我们的蛇的长度由非严格递增变为非严格递减,之后我们再2号蛇吃1号蛇,3号蛇吃2号蛇,...最后n号蛇吃n-1号蛇,这样一直反复就行。发现这个递推可以用矩阵快速幂维护,那么总复杂度为(O(n^3logM)).

    //不等,不问,不犹豫,不回头.
    #include<bits/stdc++.h>
    #define _ 0
    #define ls p<<1
    #define db double
    #define rs p<<1|1
    #define P 1000000007
    #define ll long long
    #define INF 1000000000
    #define get(x) x=read()
    #define PLI pair<ll,int>
    #define PII pair<int,int>
    #define ull unsigned long long
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define rep(x,y,z) for(int x=y;x<=z;++x)
    #define fep(x,y,z) for(int x=y;x>=z;--x)
    #define go(x) for(int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
    using namespace std;
    const int N=55;
    int n,x,M,l[N];
    struct wy
    {
    	ll a[N][N];
    	wy() {memset(a,0,sizeof(a));}
    	inline void clear(){memset(a,0,sizeof(a));}
    	wy friend operator*(wy a,wy b)
    	{
    		wy c;
    		rep(i,1,n) rep(j,1,n) rep(k,1,n) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%P;
    		return c;
    	}
    	wy friend operator^(wy a,ll y)
    	{
    		wy c;
    		rep(i,1,50) c.a[i][i]=1;
    		while(y)
    		{
    			if(y&1) c=c*a;
    			y>>=1;
    			a=a*a;
    		}
    		return c;
    	}
    }A,B,C,D;
    
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    
    int main()
    {
        //freopen("1.in","r",stdin);
        int get(T);
        while(T--)
        {
        	A.clear();B.clear();C.clear();D.clear();
        	get(n);get(x);get(M);
        	rep(i,1,n) get(l[i]);
    		sort(l+1,l+n+1);
    		rep(i,1,n) rep(j,1,i) A.a[i][j]=1;	
    		rep(i,1,n) rep(j,i,n) B.a[i][j]=1;	
    		rep(i,1,n) D.a[1][i]=l[i];
    		C=A*B;
    		int t=M/x+1;
    		C=C^(t/2);
    		if(t%2) C=C*A;
    		C=D*C;
    		if(t%2) put(C.a[1][1]);
    		else put(C.a[1][n]);
    	}
        return (0^_^0);
    }
    //以吾之血,铸吾最后的亡魂.
    
    
  • 相关阅读:
    输入输出、基本运算符、流程控制
    Node学习6-fs模块
    Node学习5-events模块
    Node学习4-Buffer模块
    Node学习3-Path模块
    Node学习2-基础知识/HelloWorld/模块调用/global/process
    Node学习1-基本概念
    gulp/bower/less知识
    AngularJS学习1-基础知识
    JavaScript学习-类/原型链/class
  • 原文地址:https://www.cnblogs.com/gcfer/p/15169085.html
Copyright © 2011-2022 走看看