[CSP-S模拟测试]:Cicada拿衣服(暴力+乱搞)

题目传送门(内部题94)


输入格式

  第一行两个整数$n,k$,代表衣服的数量和阈值。
  接下来一行$n$个数,第$i$个数$a_i$表示每件衣服的愉悦值。


输出格式

  输出一行$n$个数,第$i$个数为$r_i-l_i+1$,如果不存在这样的$l,r$,则输出$-1$即可。


数据范围与提示

$n\leqslant 10^6,0\leqslant a_i\leqslant 10^8,0\leqslant k\leqslant 10^9$


题解

正解是什么?我不知道。

乱搞就好了……

具体看代码吧,挺帅(不要脸)的。

可能是我发现这样可以过?

总之绿块块是我的!!!

感谢富豪大神的快读(从不打快读的我)。

时间复杂度:$\Theta($不要脸$)$。

期望得分:$64$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[1000001],ans[1000001];
inline int read(){
	int ss(0);char bb(getchar());
	while(bb<48||bb>57)bb=getchar();
	while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
	return ss;
}
int main()
{
	n=read(),k=read();
	for(int i=1;i<=n;i++)ans[i]=-1,a[i]=read();
	if(n<=30000)
	{
		for(int i=1;i<=n;i++)
		{
			int Min=0x3f3f3f3f,Or=0,Max=0,And=(1<<30)-1,r=-0x3f3f3f3f;
			for(int j=i;j<=n;j++)
			{
				if(a[j]<Min)Min=a[j];
				Or|=a[j];
				if(a[j]>Max)Max=a[j];
				And&=a[j];
				if(Min+Or-Max-And>=k)r=j;
			}
			int len=r-i+1;
			for(int j=i;j<=r;j++)if(len>ans[j])ans[j]=len;
		}
		for(int i=1;i<=n;i++)printf("%d ",ans[i]);
		return 0;
	}
	for(int i=1;i<=n;i++)
	{
		int Min=0x3f3f3f3f,Or=0,Max=0,And=(1<<30)-1,r=-0x3f3f3f3f;
		int minn=min(i+700,n);
		for(int j=i;j<=minn;j++)
		{
			if(a[j]<Min)Min=a[j];
			Or|=a[j];
			if(a[j]>Max)Max=a[j];
			And&=a[j];
			if(Min+Or-Max-And>=k)r=j;
		}
		int len=r-i+1;
		for(int j=i;j<=r;j++)if(len>ans[j])ans[j]=len;
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	return 0;
}

rp++

posted @ 2019-10-28 19:32  HEOI-动动  阅读(264)  评论(2编辑  收藏  举报