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;
}