zoukankan      html  css  js  c++  java
  • hdu 4027 Can you answer these queries? 线段树

    区间开根,区间求和。

    最大的int开不到10次根也会变成1。每次开根都暴力处理,最多也不过是10N的复杂度。

    所以每个节点维护一个标记,子树所代表的区间是否都小于等于1,成立就不开根了,从而维护复杂度正确性。

    注意输入的l和r可能先大后小,需要交换....

    跟BZOJ花神游历各国是一个题。

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 ll n,m,T;
     8 ll data[500000],opt[500000],sec[100005];
     9 void build(ll k,ll l,ll r)
    10 {
    11     if (l == r)
    12     {
    13         data[k] = sec[l];
    14         if (sec[l] <= 1) 
    15             opt[k] = 1;
    16         else 
    17             opt[k] = 0;
    18         return;
    19     }
    20     ll mid = l + r >> 1;
    21     build(k << 1,l,mid);
    22     build(k << 1 | 1,mid + 1,r);
    23     data[k] = data[k << 1] + data[k << 1 | 1];
    24     opt[k] = opt[k << 1] && opt[k << 1 | 1];
    25 }
    26 ll query(ll k,ll l,ll r,ll x,ll y)
    27 {
    28     if (x <= l && r <= y) return data[k];
    29     ll mid = l + r >> 1,res = 0;
    30     if (x <= mid) res += query(k << 1,l,mid,x,y);
    31     if (y > mid) res += query(k << 1 | 1,mid + 1,r,x,y);
    32     return res;
    33 }
    34 void change(ll k,ll l,ll r,ll x,ll y)
    35 {
    36     if (opt[k]) return;
    37     if (l == r)
    38     {
    39         data[k] = sqrt(data[k]);
    40         if (data[k] <= 1) opt[k] = 1;
    41         return;
    42     }
    43     ll mid = l + r >> 1;
    44     if (x <= mid) change(k << 1,l,mid,x,y);
    45     if (y > mid) change(k << 1 | 1,mid + 1,r,x,y); 
    46     data[k] = data[k << 1] + data[k << 1 | 1];
    47     opt[k] = opt[k << 1] && opt[k << 1 | 1];
    48 }
    49 int main()
    50 {
    51     while (scanf("%lld",&n) > 0)
    52     {
    53         printf("Case #%lld:
    ",++T);
    54         for (ll i = 1;i <= n;i++) scanf("%lld",&sec[i]);
    55         build(1,1,n);
    56         scanf("%lld",&m);
    57         ll tx,tl,tr;
    58         for (ll i = 1;i <= m;i++)
    59         {
    60             scanf("%lld%lld%lld",&tx,&tl,&tr);
    61             if (tl > tr)
    62                 swap(tl,tr);
    63             if (tx == 1) printf("%lld
    ",query(1,1,n,tl,tr));else
    64             change(1,1,n,tl,tr);
    65         }
    66         printf("
    ");
    67     }
    68     return 0;
    69 }
    心之所动 且就随缘去吧
  • 相关阅读:
    hdu4738(双连通分量)
    hdu4635(强连通缩点)
    hdu4612(双连通缩点+树的直径)
    poj3177(边双连通分量+缩点)
    poj3694(tarjan缩点+lca)
    hdu5171(矩阵快速幂)
    uva796(求桥数目)
    uva315(求割点数目)
    POJ1058 The Gourmet Club
    POJ1057 FILE MAPPING
  • 原文地址:https://www.cnblogs.com/iat14/p/12188968.html
Copyright © 2011-2022 走看看