Codeforces Round #275 (Div. 1)

本文探讨了两个算法问题:一是求解给定N和K的条件下,生成一个1到N的排列,使得绝对差值为K个不同值;二是解决一个序列满足多个限制条件的问题,即在序列中指定区间内元素的乘积等于给定值。通过差分数组和位运算技术高效解决这些问题。

A

题意:给一个N和一个K,求一个1到N的排列,使得abs(a1-a2),abs(a2-a3)...abs(an-1-an)为k个不同的值。

题解:易知我们最大可以凑出N-1个不同的值只要这样1,N,2,N-1,3,....即可

所以我们还按照这个方式来,到凑出来k-1个数之后,把剩下的数从小到大输出即可,这样第k个值为1。

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
int n,k,now,nowl,nowr;
int main()
{
	scanf("%d%d",&n,&k);
	now=0;nowl=1;nowr=n;
	if (n==3)
	{
		if (k==1) printf("1 2 3");
		else printf("1 3 2");
		return 0;
	}
	for (int i=1;i<=k;++i) 
	{	if (!now) 
			{
				printf("%d ",nowl);
				nowl++;
			}
			else
			{
				printf("%d ",nowr);
				nowr--;
			}
		now^=1;
	}
	if (now==1)
	for (int i=nowl;i<=nowr;++i) printf("%d ",i);
	else 
	for (int i=nowr;i>=nowl;--i) printf("%d ",i);
	return 0;
}

 B:

题意:求一个N个数的序列,使得满足M个限制条件,限制条件如下给出:

Li Ri Ki 要求a[li]&a[li+1]&a[li+2]&...&a[ri]=ki

题解:按位来做,对于每一位,我们先开一个数组x[i]来表示数列中第i个数这一位是否为1,我们来检索每一个条件,若ki这一位是1,则给li到ri这一段的每个xi都加1,这个可以通过差分在O(N)得到,这样对于每一位我们得到一个x数组,然后我们再来检索每一个条件,若ki这一位不为1,而x[li]到x[ri]均为1,则此时必为无解的情况,否则更新答案即可。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
struct node
{
	int l,r,w;
}q[100005];
int a[100005],t[100005],sum[100005],n,m,flag;
int work(int x)
{
	memset(sum,0,sizeof(sum));
	memset(t,0,sizeof(t));
	for (int i=1;i<=m;++i)
	{
		int dq=q[i].w&x;
		if (dq)
		{t[q[i].l]++;t[q[i].r+1]--;}
	}
	for (int i=1;i<=n;++i) t[i]=t[i-1]+t[i];
	for (int i=1;i<=n;++i) if (t[i]>0) t[i]=1;else t[i]=0;
	for (int i=1;i<=n;++i) sum[i]=sum[i-1]+t[i];
	for (int i=1;i<=m;++i)
	{
		int dq=q[i].w&x;
		if (!dq)
		{
			if (sum[q[i].r]-sum[q[i].l-1]==q[i].r-q[i].l+1) return 0;
		}
		else
		{
			if (sum[q[i].r]-sum[q[i].l-1]!=q[i].r-q[i].l+1) return 0;
		}
	}

	for (int i=1;i<=n;++i) if (t[i]>0) a[i]|=x;
	return 1;
}
int main()
{
	scanf("%d %d"

转载于:https://www.cnblogs.com/zscnash/p/4143948.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值