NYOJ 1068 ST(线段树插线问线)
2015-10-12 14:22
344 查看
题目:NYOJ 1068 ST
其实线段树题目贵在对树的操作有一个清晰的认识,那些事需要回溯的时候维护的,那些是可以直接维护的,如果能够直接维护就不要放到回溯的时候,这样操作简单,不容易出错。
比如这道题目,更新的时候是给【 l,r 】都加上一个值val,查询的时候成段查询一段的和喝一段的中奇数的个数。
我们在建树的时候通过回溯求出初始值的和和奇数的个数,然后更新的值就可以直接维护了,每次给某一段加一个值,我们更新到段上面,来保存这个要加的值,然后他的更新延迟到求某段和或者奇数的时候用到的时候更新,这样就很清晰了。
代码:
其实线段树题目贵在对树的操作有一个清晰的认识,那些事需要回溯的时候维护的,那些是可以直接维护的,如果能够直接维护就不要放到回溯的时候,这样操作简单,不容易出错。
比如这道题目,更新的时候是给【 l,r 】都加上一个值val,查询的时候成段查询一段的和喝一段的中奇数的个数。
我们在建树的时候通过回溯求出初始值的和和奇数的个数,然后更新的值就可以直接维护了,每次给某一段加一个值,我们更新到段上面,来保存这个要加的值,然后他的更新延迟到求某段和或者奇数的时候用到的时候更新,这样就很清晰了。
代码:
#include <cstdio> #include <cstring> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <map> #include <queue> #define Del(a,b) memset(a,b,sizeof(a)) using namespace std; const long long inf = 0x3f3f3f3f; const long long N = 1E4 + 100; struct Node { long long l,r; bool flag; long long num,sum,cnt; }; Node tree[4*N]; void yougth(long long o) { tree[o].cnt = tree[o+o].cnt + tree[o+o+1].cnt; tree[o].sum = tree[o+o].sum + tree[o+o+1].sum; } void build(long long o,long long l,long long r) { tree[o].l = l; tree[o].r = r; tree[o].num = tree[o].sum = tree[o].cnt = 0; tree[o].flag = false; if(l==r) { long long x; scanf("%lld",&x); if(x%2) tree[o].cnt = 1; tree[o].sum = x; tree[o].flag = true; return ; } long long mid = (l+r)/2; build(o+o,l,mid); build(o+o+1,mid+1,r); yougth(o); } void push_update(long long o) { if(tree[o].flag) { tree[o].flag = false; //tree[o+o].num = tree[o+o+1].num = tree[o].num; SB tree[o+o].num += tree[o].num; tree[o+o+1].num += tree[o].num; tree[o+o].flag = tree[o+o+1].flag = true; tree[o].num = 0; } } void update(long long o,long long l,long long r,long long x) { if(tree[o].l==l && tree[o].r == r) { tree[o].num += x; tree[o].flag = true; return ; } push_update(o); long long mid=(tree[o].l+tree[o].r)>>1; if(r<=mid) update(o+o,l,r,x); else if(l>mid) update(o+o+1,l,r,x); else { update(o+o,l,mid,x); update(o+o+1,mid+1,r,x); } } long long query(long long o,long long l,long long r,bool ok) { if(tree[o].l == l && tree[o].r == r && tree[o].flag) { long long tmp = tree[o].r-tree[o].l+1; if(ok) return tree[o].sum + tmp*tree[o].num; return tree[o].num%2?(tmp-tree[o].cnt):tree[o].cnt; } push_update(o); long long mid=(tree[o].l+tree[o].r)>>1; if(r<=mid) return query(o+o,l,r,ok); else if(l>mid) return query(o+o+1,l,r,ok); else { return query(o+o,l,mid,ok) + query(o+o+1,mid+1,r,ok); } } int main() { // freopen("Input.txt","r",stdin); // freopen("Out.txt","w",stdout); long long n,m; while(~scanf("%lld%lld",&n,&m)) { build(1,1,n); while(m--) { getchar(); char c[10];; long long a,b,x; scanf("%s %lld%lld",c,&a,&b); long long len = strlen(c); char flag = '0'; for(long long k=0;k<len;++k) { if(c[k]>='A' && c[k]<='Z') { flag = c[k]; break; } } if(flag=='A') { scanf("%lld",&x); update(1,a,b,x); } else if(flag=='S') printf("%lld\n",query(1,a,b,true)); else if(flag == 'Q') printf("%lld\n",query(1,a,b,false)); } } return 0; }
相关文章推荐
- hdu 1969 Pie(二分查找)
- poj 3104 Drying(二分查找)
- android调用WebService实例分析
- hdu 2106 decimal system
- poj 1837 Balance(背包)
- hdu1042 N!
- zabbix------使用自带模版监控windows主机
- hdu1002 A + B Problem II(大数题)
- 区间DP(总结)
- 接口与回调
- hdu 1240 Asteroids! (bfs)
- 矩阵(神奇算法)
- hdu 1241Oil Deposits(BFS)
- 关于利用Jsoup解析HTML中&nbsp;变成非传统空格或乱码问题解决方法
- git操作
- <iframe>标签自适应高度和宽度
- Android中的LayoutInflater和inflate
- zoj2001 Adding Reversed Numbers
- hdu 1070 Milk(贪心)
- hdu 2545 树上战争(并查集)