2020牛客暑期多校训练营(第六场)BCEK

232 北林一队  北京林业大学 4 10:02:35

B:队友写的,等会再看看。

#include
#include
#include
using namespace std;
#define mod 1000000007
#define ll long long
#define N 30000007
int n,a[N],b[N],mul[N];
 
int Pow(int a,int b){
    int res=1;
    while(b){
        if(b%2)res=1ll*res*a%mod;
        b>>=1;a=1ll*a*a%mod;
    }
    return res;
}
int p[N];
void init(){
    int base=1;a[0]=b[0]=p[0]=1;
    int rev2=Pow(2,mod-2);
    for(register int i=1;i<=2e7;i++){
        base=2ll*base%mod;
        a[i]=1ll*a[i-1]*(base-1+mod)%mod;
        p[i]=1ll*p[i-1]*rev2%mod;
        b[i]=1ll*b[i-1]*p[i]%mod;
    }
    for(register int i=1;i<=2e7;i++)
        mul[i]=1ll*a[i]*b[i]%mod;
 
    for(register int i=2;i<=2e7;i++)
        mul[i]^=mul[i-1];
}
 
int main(){
    init();
 
    int t;cin>>t;
    while(t--){
        cin>>n;
        printf("%d\n",mul[n]);
    }
}

C:

只选一列是最优解:

我刚开始写01分数规划,其实没必要,01分数规划适用于只选k个等有限制条件的情况下。(之前还真没思考过这个问题,在这题被卡精度后,才思考这个情况的。。)

#include
#include
#include
using namespace std;
#define N 505
int a[N][N];
int n,m;
 
int main(){
    int t;cin>>t;
    while(t--){
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);
        double ans=0;
        for(int j=1;j<=m;j++) {
            int sum=0;
            for (int i=1;i<=n;i++)
                sum+=a[i][j],ans=max(ans,1.0*sum/a[i][j]);
        }
        printf("%.8lf\n",ans);
    }
}

E:

n n-2,2,n-4,4……,3,n-3,1,n-1;

这样少1,2,3,……个数都能构造出来

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[M];
int main()
{
     
    int n,k;
    scanf("%d%d",&n,&k);
    if(((1+n)*n/2)%n!=k)
    {
        puts("-1");
        return 0;
    }
    if(n&1)
    {
        int tp=n;
        for(int i=1;i<=n;i+=2)
            a[i]=tp,tp--;
        tp=1;
        for(int i=2;i<=n;i+=2)
            a[i]=tp,tp++;
    }
    else
    {
        int tp=n-1;
        a[n]=n;
        for(int i=1;i

K:

2020牛客暑期多校训练营(第六场)BCEK_第1张图片

用RMQ维护最大值即可。。

懒得再打一遍了。

 

这题有些收获:维护一个序列1-n是一个排列用RMQ可以维护。这个比较巧妙啊!

而且可以维护区间无重复元素,甚至可以用线段树搞一写东西。

不过话说区间种类个数不就是这种思路嘛。。。。(qaq)

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 5e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int n;
int a[M],c[M];
int dp[M][23];
int lg[M];
void RMQ()
{
	for(int i=1;i<=n;i++)
		dp[i][0]=a[i];
	for(int j=1;(1<r)return 0;
	int k=lg[r-l+1];
	return max(dp[l][k],dp[r-(1<mp;
int main()
{
	int T;
	scanf("%d",&T);
	lg[0]=-1;for(int i=1;i>1]+1;
	while(T--)
	{
		int k;
		scanf("%d%d",&n,&k);
		int mx=0;
		for(int i=1;i<=n;i++)scanf("%d",&c[i]),mx=max(c[i],mx);
		if(mx>k)
		{
			puts("NO");
			continue;
		}
		mp.clear();
		for(int i=1;i<=n;i++)
		{
			a[i]=mp[c[i]];
			mp[c[i]]=i;
		}
		RMQ();
		bool flag=false;
		for(int i=0;i<=k;i++)
		{
			if(qu(1,i)>=1)break;
			bool tp=true;
			for(int j=i+1;j<=n;j+=k)
				if(qu(j,min(j+k-1,n))>=j)tp=false;
			if(tp)
			{
				flag=true;
				break;
			}
		}
		if(flag)puts("YES");
		else puts("NO");
	}
	return 0;
}
/*
3
12 3
3 1 1 2 3 1 2 3 1 2 1 2
10 3
2 1 3 1 2 3 2 1 2 1
*/

 

你可能感兴趣的:(2020多校牛客)