hdu 4046 Panda(线段树+单点更新)
2013-08-06 09:47
453 查看
原题友情链接直通车~点击此处查看原题~
2011年北京赛区网络赛的一道水题..............按照自己现在的水平还算不上所谓的水题。
考察:区间更新跟区间查询,线段树or树状数组。
这里我用的是线段树。
题意:一个小盆友要给他的女神示爱,但是他要赶时间,没时间写那么多,写的信上只有“w”和''b"。给出一个规定,出线连续的字符串是wbw时表示一个Love。第一行输入一个T,
表示测试数据的组数。紧接着输入n,m。分别表示这封信上有n个字和下面有m个操作。
m个操作中有两种情况。
Type 0: answer how many love between L and R. (0<=L<=R<n)
Type 1: change the kth character to ch(0<=k<n and ch is ‘b’ or ‘w’) 也就是说 “0”表示查询,“1”表示更新
这个题跟容易想的到线段树或者是树状数组来解。有着很明显的区间操作要求。然后,这个题最大的难点就在于叶子结点value值代表的含义。
博主在一开始做的时候就是一直想不到如何来建树。看大神的解答是若letter[l] == 1,则表示letter[l-2],letter[l-1],letter[l]可以达到上面的要求。
有人会问,这么查询的话正好从l开始,不是就错了吗?这里有一个巧妙的处理是在查询的时候查询的区间是(l+2,r)。就避免的上述问题。
最后一点就是更新了。当你更新一点后,因为是用第三个位置来表示这段字符串是否符合要求。在更新完l点也要更新l+1,跟l+2,的值。所以每次更新最多会出现三次单点更新操作。(想想看,为什么?当l+1,或者是l+2越出n的范围就不用在更新了)
还有一个小细节就是当前处理的区间长度不满足3的时候直接输出0,这个是显然的。
具体的实现过程看代码。
2011年北京赛区网络赛的一道水题..............按照自己现在的水平还算不上所谓的水题。
考察:区间更新跟区间查询,线段树or树状数组。
这里我用的是线段树。
题意:一个小盆友要给他的女神示爱,但是他要赶时间,没时间写那么多,写的信上只有“w”和''b"。给出一个规定,出线连续的字符串是wbw时表示一个Love。第一行输入一个T,
表示测试数据的组数。紧接着输入n,m。分别表示这封信上有n个字和下面有m个操作。
m个操作中有两种情况。
Type 0: answer how many love between L and R. (0<=L<=R<n)
Type 1: change the kth character to ch(0<=k<n and ch is ‘b’ or ‘w’) 也就是说 “0”表示查询,“1”表示更新
这个题跟容易想的到线段树或者是树状数组来解。有着很明显的区间操作要求。然后,这个题最大的难点就在于叶子结点value值代表的含义。
博主在一开始做的时候就是一直想不到如何来建树。看大神的解答是若letter[l] == 1,则表示letter[l-2],letter[l-1],letter[l]可以达到上面的要求。
有人会问,这么查询的话正好从l开始,不是就错了吗?这里有一个巧妙的处理是在查询的时候查询的区间是(l+2,r)。就避免的上述问题。
最后一点就是更新了。当你更新一点后,因为是用第三个位置来表示这段字符串是否符合要求。在更新完l点也要更新l+1,跟l+2,的值。所以每次更新最多会出现三次单点更新操作。(想想看,为什么?当l+1,或者是l+2越出n的范围就不用在更新了)
还有一个小细节就是当前处理的区间长度不满足3的时候直接输出0,这个是显然的。
具体的实现过程看代码。
#include<cstdio> #include<cstring> #define ll(x) (x)<<1 #define rr(x) ll(x)|1 using namespace std; const int Maxsize = 50010; typedef struct { int l,r,value; } Tree; Tree tree[Maxsize<<2]; char letter[Maxsize]; void Pushup(int v) { tree[v].value = tree[ll(v)].value + tree[rr(v)].value; } void build(int v,int l,int r)/*建树*/ { tree[v].l = l; tree[v].r = r; tree[v].value = 0; if(l == r) { if( l <= 2) { tree[v].value = 0; return; } if( letter[l] == 'w' && letter[l-1] == 'b' && letter[l-2] == 'w') { tree[v].value = 1; } else { tree[v].value = 0; } return; } int mid = ( l + r)>>1; build(ll(v),l,mid); build(rr(v),mid+1,r); Pushup(v); } void update(int v,int k,char t)/*更新*/ { if(tree[v].l == k && tree[v].r == k) { letter[k] = t; if( k <= 2)return; if(letter[k] == 'w' && letter[k-1] == 'b' && letter[k-2] == 'w') { tree[v].value = 1; } else { tree[v].value = 0; } return; } int mid = (tree[v].l + tree[v].r)>>1; if(k <= mid) { update(ll(v),k,t); } else { update(rr(v),k,t); } Pushup(v); } int query(int v,int l,int r)/*区间查询*/ { if(tree[v].l == l && tree[v].r == r) { return tree[v].value; } int mid = (tree[v].l + tree[v].r)>>1; if(r <= mid) { return query(ll(v),l,r); } else { if(l > mid) { return query(rr(v),l,r); } else { return query(ll(v),l,mid) + query(rr(v),mid+1,r); } } } int main() { int ncase,casen = 0;/*ncase表示测试数据的组数,casen表示当前是第几组*/ scanf("%d",&ncase); while(ncase--) { memset(tree,0,sizeof(tree)); int n,m; scanf("%d %d",&n,&m); letter[0] = 0; scanf("%s",letter+1);/*字符串下标从1开始*/ build(1,1,n); int k,a,b; char t[2]; printf("Case %d:\n",++casen); for(int i = 0 ; i < m ; i++) { scanf("%d",&k); if(!k) { scanf("%d %d",&a,&b); if(b-a < 2 || b < 2)/*不满足三个字母的最基本条件*/ { printf("0\n"); } else { printf("%d\n",query(1,a+3,b+1));/*查询*/ } } else { scanf("%d %s",&a,t); update(1,a+1,t[0]);/*依次进行单点更新*/ if( a+1 < n) { update(1,a+2,letter[a+2]); } if( a+2 < n) { update(1,a+3,letter[a+3]); } } } } return 0; }
相关文章推荐
- HDU 4046 Panda(线段树单点更新)
- hdu 4046 Panda (线段树 单点更新 区间查询)
- hdu 4046 Panda (线段树,单点更新,区间求和)
- HDU 4046 - Panda (线段树 + 单点更新)
- hdu 4046 Panda 线段树 单点修改 求区间010个数
- HDU 1754 I Hate It(线段树 单点更新 区间最大值)
- HdU 4046 Panda 线段树
- [ACM] hdu 1754 I Hate It (线段树,单点更新)
- hdu 1754 线段树区间最大值 单点更新
- hdu1166敌兵布阵(线段树---单点更新,区间求值)
- HDU 1754 B I Hate It 线段树 单点更新 区间最大值 模板
- hdu 1556 Color the ball(线段树 区间更新单点查询)
- HDU 4027 Can you answer these queries?(线段树单点更新+询问+神坑)
- HDU 4339 Query【线段树】单点更新,动态查询
- HDU 1166 敌兵布阵 线段树,单点更新
- HDU 1754 单点更新 区间求和 zkw线段树 + 递归线段树
- HDU 1166(线段树 单点更新 区域求值)
- HDU 1754 I hate it 【线段树--单点更新,区间最值】
- HDU 1540Tunnel Warfare Tunnel Warfare (线段树- 区间合并-单点更新查询)
- HDU 4521 小明系列问题--小明序列(加强版LIS+线段树单点更新)