HDU4027 Can you answer these queries 线段树区间求和+剪枝

来源:互联网 发布:上海品牌知恩女装 编辑:程序博客网 时间:2024/04/27 18:27

给了你n,然后n个数字在一个数组中,接下来m个询问,每个询问三个数字 t,x,y,若t==0,那么修改区间[x,y]的每一个值,变为原来每个位置上的数 开根号取整,若t==1,那么对区间[x,y]求和


由于n,m,很大,所以树状数组铁定超时,若直接用线段树来做区间修改,那么也是超时,这类题目没别的方法了,静心剪枝,发现题目给的数据范围为2^63,有没有发现,2^63开根号 绝对不需要开10次,就能到1,到1以后就不需要再开了,意思就是若有某个区间[x,y]每一个点的值都为1时,这一段区间事实上是不需要处理的,怎么判断呢,简单,这个区间的和 等于 区间大小就是了,

都改好了 也不TLE了,也不WA了,但是一直RE,搞不懂,直到最后也没搞懂,最后有队友说题目给的区间 [x,y], x的值不一定比y小,所以需要判别一下,题目在交代x,y的取值范围时,确实没有说x<y,所以算是自己粗心吧,长记性了


#include<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<queue>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>#include<cctype>#define ll long long#define LL __int64#define eps 1e-8#define inf 0xfffffff//const ll INF = 1ll<<61;using namespace std;//vector<pair<int,int> > G;//typedef pair<int,int > P;//vector<pair<int,int> > ::iterator iter;////map<ll,int >mp;//map<ll,int >::iterator p;const int N = 100000 + 5;typedef struct Node {int l,r;LL sum;};Node tree[N * 4];LL a[N];int n;void build_tree(int left,int right,int id) {tree[id].l = left;tree[id].r = right;tree[id].sum = 0;if(left == right) {tree[id].sum = a[left];return;}int mid = (left + right)>>1;build_tree(left,mid,id * 2);build_tree(mid+1,right,id * 2 + 1);tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;}void update(int left,int right,int id) {if(tree[id].l == left && tree[id].r == right) {if(tree[id].sum ==right - left + 1) return;//区间和等于区间长度没必要更新处理else if(left == right) {tree[id].sum = sqrt(tree[id].sum * 1.0);return ;}}LL mid = (tree[id].l + tree[id].r)>>1;if(right <= mid) update(left,right,id * 2);else  if(left > mid)update(left,right,id * 2 + 1);else {update(left,mid,id * 2);update(mid + 1,right,id * 2 + 1);}tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;}LL query(int left,int right,int id) {if(tree[id].l == left && tree[id].r == right) return tree[id].sum;int mid = (tree[id].l + tree[id].r)>>1;if(right <= mid)return query(left,right,id * 2);else if(left > mid) return query(left,right,id * 2 + 1);elsereturn query(left,mid,id * 2) + query(mid + 1,right,id * 2 + 1);}int main() {intCase = 0;while(scanf("%d",&n) == 1) {for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);build_tree(1,n,1);int m;scanf("%d",&m);int t,x,y;printf("Case #%d:\n",++Case);while(m--) {scanf("%d %d %d",&t,&x,&y);if(x > y)swap(x,y);if(t == 0) {update(x,y,1);}else {printf("%I64d\n",query(x,y,1));}}puts("");}return 0;}




0 0
原创粉丝点击