hdu 3275线段树加延迟标记
2011-09-26 21:10
411 查看
Light
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 463 Accepted Submission(s): 145
[align=left]Problem Description[/align]
Felicia was given a long string of fancy lanterns, but not all of them are on to light the night. Felicia felt bad about that and he wants to light up all the lanterns. There is a kind of magic switch which can change the states of k continuous lanterns. Once you choose k continuous lanterns and install a switch on them, the states of all k continuous lanterns can be changed together (on ->off or off ->on), but you cannot choose some ones be changed and some ones not be changed.
Felicia wants to buy as few switches as possible so that he can install them to turn on all the lanterns. Please notice that each switch must control exactly k continuous lanterns.
[align=left]Input[/align]
The input consists of multiple test cases. The first line of each case contains integers n(0 < n <= 100000), which is the length of that string of fancy lanterns, and k(0 <= k <= n), which is the number of continuous lanterns that a switch will control. The next line consists of a string of “01” with length n. “1” means that lantern is on and “0” means off. Your job is turn all the “0” to “1”.
The last test case is followed by a line containing two zeros.
[align=left]Output[/align]
If you cannot finish this job, output “-1” or you should output the minimum number switches that you should buy to turn on all the lanterns.
[align=left]Sample Input[/align]
4 2
0000
4 2
1001
4 2
0110
4 2
0111
0 0
[align=left]Sample Output[/align]
2
1
3
-1
注意每个节点的信息的储存,用到了贪心加延迟标记,每次都是把嘴左边的第一个0取反;
/*
Name:
Copyright:
Author:
Date: 26/09/11 20:59
Description:
*/
#include<iostream>
#include<algorithm>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<set>
#include<map>
#include<cmath>
using namespace std;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define maxn 100002
int n,k;
char s[maxn];
struct node { int left,right,sum,sum0,col; };
struct Seg
{ node tree[maxn*4];
void pushdown(int p) // pushdown 是在有更新的情况下,查询到的时候,干的
{ if(tree[p].left==tree[p].right||tree[p].col==0) return;
swap(tree[L(p)].sum,tree[L(p)].sum0); swap(tree[R(p)].sum,tree[R(p)].sum0);
tree[L(p)].col=!tree[L(p)].col; tree[R(p)].col=!tree[R(p)].col; tree[p].col=!tree[p].col;
}
void update(int p)
{ tree[p].sum=tree[L(p)].sum+tree[R(p)].sum;
tree[p].sum0=tree[L(p)].sum0+tree[R(p)].sum0;
}
void build(int p,int left,int right)
{ tree[p].left=left; tree[p].right=right; tree[p].col=0;
if(left==right)
{ if(s[left]=='1') { tree[p].sum=1; tree[p].sum0=0; }
else { tree[p].sum=0; tree[p].sum0=1; }
return;
}
int mid=(left+right)>>1;
build(L(p),left,mid); build(R(p),mid+1,right);
update(p);
}
void insert(int p,int left,int right)
{ if(left<=tree[p].left&&tree[p].right<=right)
{ tree[p].col=!tree[p].col; swap(tree[p].sum,tree[p].sum0); return;
}
pushdown(p);
int mid=(tree[p].left+tree[p].right)>>1;
if(left<=mid) insert(L(p),left,right);
if(right>mid) insert(R(p),left,right);
update(p);
}
int query(int p)
{ if(tree[p].left==tree[p].right) return tree[p].left;
pushdown(p);
int ans=-1;
if(tree[L(p)].sum0) ans=query(L(p));
else if(tree[R(p)].sum0) ans=query(R(p));
update(p);
return ans;
}
}seg;
int main()
{ int i,j,k,len,ans,flag,pos;
while(scanf("%d%d",&n,&k)!=EOF)
{ if(n==0&&k==0) break;
getchar();
scanf(" %s",s+1);
len=strlen(s+1);
seg.build(1,1,len);
ans=0; flag=0;
for(i=1;i<=len;i++)
{ if(s[i]=='0')
{ flag=1;
break;
}
}
if(k==0) // 一开始这个没加 ,RE 了一次,我觉得应该是 TLE 的,不加的话,后面是死循环
{ if(seg.tree[1].sum==len) puts("0");
else puts("-1");
continue;
}
if(flag==0) { puts("0"); continue; }
flag=0; ans=0;
while((pos=seg.query(1))!=-1)
{ if(pos+k-1>len) { flag=1; puts("-1"); break; }
seg.insert(1,pos,pos+k-1);
ans++;
}
if(flag==0) printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- hdu 3275(线段树的延迟标记,我被坑了)
- 线段树,区间更改,延迟标记 hdu 1698
- 线段树(类似延迟标记) HDU - 4027
- hdu 3911 Black And White(线段树的延迟标记法)
- 【hdu】 Just a Hook (线段树 -成段更新,延迟标记)
- HDU 1698 Just a Hook (线段树延迟标记(lazy))
- 【线段树延迟更新】HDU 3275
- HDU 1698 JUST a hook (线段树 成段替换 区间求和 延迟标记)
- E - Just a Hook HDU 1698 (线段树+类似延迟标记)
- hdu 3397 Sequence operation(线段树的延迟标记)
- hdu 1698 Just a Hook(线段树成段更新+延迟标记).
- hdu1698-Just a Hook-线段树-整段区间的替换(延迟标记)
- EOJ 2525 线段树 + 延迟标记
- HDU 1698 Just a Hook(线段树 + Lazy Tag(延迟更新))
- hdu 4027 Can you answer these queries?(线段树)(单点更新 但需要标记记录剪枝)
- HDU 3954 Level up (线段树特殊懒惰标记)
- codevs 1082 线段树练习 3 区间更新+延迟标记
- hdu 1556 Color the ball (线段树,延迟更新)
- poj 3225 Help with Intervals -线段树-延迟标记-区间交并补
- [uva11992]Fast Matrix Operations(多延迟标记,线段树,区间更新)