D - Can you answer these queries? (线段树+剪枝)

Posted -ackerman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D - Can you answer these queries? (线段树+剪枝)相关的知识,希望对你有一定的参考价值。

题目链接:https://vjudge.net/contest/332656#problem/D

 

思路:因为根号运算n衰减的很快,所以在极少数的操作内它就会变成1,所以当整个区间内的值都变成1时直接返回,反之暴力更新叶子结点就好

 

  1 #include <math.h>
  2 #include <stdio.h>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <string>
  6 #include <string.h>
  7 #include <vector>
  8 #include <map>
  9 #include <random>
 10 
 11 
 12 #define LL long long
 13 
 14 const int maxn = 1e5 + 10;
 15 
 16 
 17 LL arr[maxn];
 18 struct segment_tree {
 19     int l,r;
 20     LL val;
 21 }tree[maxn<<2];
 22 
 23 
 24 void pushup(int nod ) {
 25     tree[nod].val = (tree[nod<<1].val + tree[(nod<<1)+1].val);
 26 }
 27 
 28 
 29 void build(int l,int r,int nod) {
 30     tree[nod].l = l;
 31     tree[nod].r = r;
 32     if (l == r) {
 33         tree[nod].val = arr[l];
 34         return ;
 35     }
 36     int mid = (l + r) >> 1;
 37     build(l,mid,nod<<1);
 38     build(mid+1,r,(nod<<1)+1);
 39     pushup(nod);
 40 }
 41 
 42 void modify(int x,int y,int k=1) {
 43     int l = tree[k].l,r = tree[k].r;
 44     if (l == r) {
 45         tree[k].val = std::sqrt(tree[k].val);
 46         return ;
 47     }
 48     if (x <= l && y >= r && tree[k].val == r-l+1)
 49         return ;
 50     int mid = (l + r ) >> 1;
 51     if (x <= mid)
 52         modify(x,y,k<<1);
 53     if (y > mid) {
 54         modify(x,y,(k<<1)+1);
 55     }
 56     pushup(k);
 57 }
 58 
 59 LL query(int x,int y,int k=1) {
 60     int l = tree[k].l,r = tree[k].r;
 61     if (x <= l && y >= r) {
 62         return tree[k].val;
 63     }
 64     int mid = (l + r) >> 1;
 65     LL sum = 0;
 66     if (x <= mid)
 67         sum += query(x,y,k<<1);
 68     if (y > mid) {
 69         sum += query(x,y,(k<<1)+1);
 70     }
 71     return sum;
 72 }
 73 
 74 int main() {
 75     int n;
 76     int t = 1;
 77     while (~scanf("%d",&n)) {
 78         for (int i=1;i<=n;i++) {
 79             scanf("%lld",&arr[i]);
 80         }
 81         build(1,n,1);
 82         int m;
 83         scanf("%d",&m);
 84         printf("Case #%d:
",t++);
 85         int x,y,z;
 86         while (m--) {
 87             scanf("%d%d%d",&z,&x,&y);
 88             if (x > y)
 89                 std::swap(x,y);
 90             if (!z) {
 91                 modify(x,y);
 92             }
 93             else {
 94                 printf("%lld
",query(x,y));
 95             }
 96         }
 97         printf("
");
 98     }
 99     return 0;
100 }

 

以上是关于D - Can you answer these queries? (线段树+剪枝)的主要内容,如果未能解决你的问题,请参考以下文章

SP6779 GSS7 - Can you answer these queries VII

HDU 4027 Can you answer these queries? (线段树)

模板——线段树维护最大子段和 SP1716 GSS3 - Can you answer these queries III

Can you answer these queries? HDU - 4027 (区间修改+区间查询)

HDU4027 Can you answer these queries? —— 线段树 区间修改

HDU-Can you answer these queries? (线段树+区间修改)