您的位置:首页 > 其它

【线段树延迟更新】HDU 3275

2012-02-14 06:58 357 查看
以后再补解题报告,先贴代码http://acm.hdu.edu.cn/showproblem.php?pid=3275

#define N 100005
char str
;
int sum0[N*4],sum1[N*4];
bool mark[N*4];
void up(int id){
sum0[id] = sum0[id<<1] + sum0[id<<1|1];
sum1[id] = sum1[id<<1] + sum1[id<<1|1];
}
void build(int s,int t,int id){
mark[id] = 0;
if(s == t){
if(str[s] == '0'){
sum0[id] = 1;
sum1[id] = 0;
} else {
sum0[id] = 0;
sum1[id] = 1;
}
return ;
}
int mid = (s+t)>>1;
build(s,mid,id<<1);
build(mid+1,t,id<<1|1);
up(id);
}
void rev(int id){
mark[id] = !mark[id];
swap(sum0[id],sum1[id]);
}
void down(int id){
if(mark[id]){
mark[id] = 0;
rev(id<<1);
rev(id<<1|1);
}
}
void solve(int s,int t,int id,int l,int r){
if(s<=l && r<=t){
rev(id);
return ;
}
down(id);
int mid = (l+r)>>1;
if(s<=mid)solve(s,t,id<<1,l,mid);
if(mid+1<=t)solve(s,t,id<<1|1,mid+1,r);
up(id);
}
int find(int s,int t,int id){
if(s == t){
if(sum0[id]>0)return s;
}
down(id);
int mid = (s+t)>>1;
if(sum0[id<<1])return find(s,mid,id<<1);
else if(sum0[id<<1|1])return find(mid+1,t,id<<1|1);
else return 0;
}
int main(){
int n,k;
while(scanf("%d%d",&n,&k) && (n+k)){
int i,j;
scanf("%s",str+1);
bool ok = 1;
int len = strlen(str+1);
for(i=1;i<=len;i++){
if(str[i] == '0'){
ok = 0;
break;
}
}
if(ok){
printf("0\n");
continue;
}
if(k == 0){
if(ok)printf("0\n");
else printf("-1\n");
} else {
build(1,n,1);
int ans = 0;
while(1){
int pos = find(1,n,1);//cout<<pos<<"!"<<endl;
if(pos == 0){
ok = 1;
break;
}
if(ans>n-k+1 || pos+k-1>n){
ok = 0;
break;
}
solve(pos,pos+k-1,1,1,n);
ans++;
}
if(!ok){
printf("-1\n");
} else {
printf("%d\n",ans);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: