codechef: BINARY, Binary Movements

模拟题

把每堆 0 搞成一块丢进双端队列,每次出现 1 就 XJB 乱搞模拟就好了(可能想想还是很麻烦的?尤其对于我这种懒癌晚期?)

复杂度均摊 O n

//by Judge
#include<bits/stdc++.h>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define ll long long
using namespace std;
const int M=1e6+3;
typedef int arr[M<<1];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline bool cmax(int& a,int b){return a<b?a=b,1:0;}
inline bool cmin(int& a,int b){return a>b?a=b,1:0;}
inline int read(){ int x=0,f=1; char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int C=-1,Z;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
int n,m,r,top,tot; arr vis,pre,ans;
int main(){
	fp(i,1,read()){
		n=read(),m=read();
		r=top=M,tot=0;
		fp(i,M-n-1,M) pre[i]=i-1;
		Rg int cnt=0,x=0;
		fp(i,1,n){
			x=read();
			if(x){
				if(++top-m>0)
					tot-=vis[top-m];
				if(cnt){
					while(--cnt)
						tot+=(r>top-m),
						vis[r]=1,r=pre[r];
					vis[top]=1,++tot;
				} else pre[top]=r,r=top;
				ans[i-tot]=1;
			} else ++cnt;
		}
		fp(i,1,n) sr[++C]=48+ans[i],sr[++C]=' ';
		sr[C]='\n';
		memset(vis+M-n,0,(n+2)<<2);
		memset(pre+M-n,0,(n+2)<<2);
		memset(vis+M,0,(n+2)<<2);
		memset(pre+M,0,(n+2)<<2);
		memset(ans,0,sizeof ans);
	} return Ot(),0;
}
posted @ 2019-05-14 17:39  Jμdge  阅读(195)  评论(0编辑  收藏  举报