• Can you answer these queries?(HDU4027+势能线段树)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027

    题目:

    题意:n个数,每次区间更新将其数值变成它的根号倍(向下取整),区间查询数值和。

    思路:易知这题的lazy标记是不好打的,但是我们发现当这个数取根号直到变成1时就不需要更新了,像这种无法打标记并且经过多次操作后就不需要操作的线段树叫做势能线段树。在需要更新时我们一直暴力到它的叶子节点,当某个区间无法更新时我们将其的flag设为0,对于某个节点的flag就等于它的左右子节点的flag取或。

    代码实现如下:

      1 #include <set>
      2 #include <map>
      3 #include <queue>
      4 #include <stack>
      5 #include <cmath>
      6 #include <bitset>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstdlib>
     11 #include <cstring>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 
     16 typedef long long ll;
     17 typedef unsigned long long ull;
     18 
     19 #define lson i<<1,l,mid
     20 #define rson i<<1|1,mid+1,r
     21 #define bug printf("*********
    ");
     22 #define FIN freopen("D://code//in.txt", "r", stdin);
     23 #define debug(x) cout<<"["<<x<<"]" <<endl;
     24 #define IO ios::sync_with_stdio(false),cin.tie(0);
     25 
     26 const double eps = 1e-8;
     27 const int mod = 1e8;
     28 const int maxn = 1e5 + 7;
     29 const double pi = acos(-1);
     30 const int inf = 0x3f3f3f3f;
     31 const ll INF = 0x3f3f3f3f3f3f3f3f;
     32 
     33 inline int read() {//读入挂
     34     int ret = 0, c, f = 1;
     35     for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
     36     if(c == '-') f = -1, c = getchar();
     37     for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
     38     if(f < 0) ret = -ret;
     39     return ret;
     40 }
     41 
     42 int n, q, op, x, y;
     43 
     44 struct node {
     45     int l, r, flag;
     46     ll sum;
     47 }segtree[maxn*4];
     48 
     49 void push_up(int i) {
     50     segtree[i].sum = segtree[i*2].sum + segtree[i*2+1].sum;
     51     segtree[i].flag = segtree[i*2].flag | segtree[i*2+1].flag;
     52 }
     53 
     54 void build(int i, int l, int r) {
     55     segtree[i].l = l, segtree[i].r = r, segtree[i].flag = 1;
     56     if(l == r) {
     57         scanf("%lld", &segtree[i].sum);
     58         if(segtree[i].sum <= 1) segtree[i].flag = 0;
     59         return;
     60     }
     61     int mid = (l + r) >> 1;
     62     build(lson);
     63     build(rson);
     64     push_up(i);
     65 }
     66 
     67 void update(int i, int l, int r) {
     68     if(!segtree[i].flag) return;
     69     if(segtree[i].l == segtree[i].r) {
     70         if(segtree[i].flag) {
     71             segtree[i].sum = sqrt(segtree[i].sum);
     72             if(segtree[i].sum <= 1) segtree[i].flag = 0;
     73         }
     74         return;
     75     }
     76     int mid = (segtree[i].l + segtree[i].r) >> 1;
     77     if(r <= mid) {
     78         if(segtree[i*2].flag)
     79             update(i*2, l, r);
     80     }
     81     else if(l > mid) {
     82         if(segtree[i*2+1].flag)
     83             update(i*2+1, l, r);
     84     }
     85     else {
     86         if(segtree[i*2].flag) update(lson);
     87         if(segtree[i*2+1].flag) update(rson);
     88     }
     89     push_up(i);
     90 }
     91 
     92 ll query(int i, int l, int r) {
     93     if(segtree[i].l == l && segtree[i].r == r) {
     94         return segtree[i].sum;
     95     }
     96     int mid = (segtree[i].l + segtree[i].r) >> 1;
     97     if(l > mid) return query(i * 2 + 1, l, r);
     98     else if(r <= mid) return query(i * 2, l, r);
     99     else return query(lson) + query(rson);
    100 }
    101 
    102 int main() {
    103     //FIN;
    104     int icase = 0;
    105     while(~scanf("%d", &n)) {
    106         build(1, 1, n);
    107         printf("Case #%d:
    ", ++icase);
    108         scanf("%d", &q);
    109         while(q--) {
    110             scanf("%d%d%d", &op, &x, &y);
    111             int a = max(x, y), b = min(x, y);
    112             if(op == 0) {
    113                 update(1, b, a);
    114             } else {
    115                 printf("%lld
    ", query(1, b, a));
    116             }
    117         }
    118         printf("
    ");
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    web攻击
    HTTP与HTTPS
    HTTP确认访问用户身份的认证
    Http协议(三)返回结果的HTTP状态码
    HTTP协议四(http首部)
    HTTP协议(二)报文信息
    HTTP协议(一)
    Windows10 如何设置软件开机自起动和关闭
    获取Chrome版本并下载匹配的chromedriver
    多线程Runnable
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9366879.html
Copyright © 2020-2023  润新知