标签:io ar os sp for on div 问题 bs
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",&n,&m);
memset