zoukankan      html  css  js  c++  java
  • BZOJ-3211-花神游历各国(线段树)

    Description

     

    Input

     

    Output

    每次x=1时,每行一个整数,表示这次旅行的开心度

    Sample Input

    4

    1 100 5 5

    5

    1 1 2

    2 1 2

    1 1 2

    2 2 3

    1 1 4

    Sample Output

    101

    11

    11

    HINT

    对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9

    Source

    SPOJ2713 gss4 数据已加强

    题解

    这道题和以前考的一道题差不多(那道题是区间取模)

    这道题是区间开根,和取模相似的,开根次数也是有限的,所以我们可以用线段树来维护一段区间,当区间内都是0或1的时候就不用再做了

     1 #include<bits/stdc++.h>
     2 #define N 100005
     3 #define ll long long
     4 using namespace std;
     5 int n,m;
     6 int a[N];
     7 ll tree[4*N];
     8 bool flag[4*N];
     9 inline int read(){
    10     int x=0,f=1; char ch=getchar();
    11     while (ch>'9'||ch<'0'){ if (ch=='-') f=-1; ch=getchar(); }
    12     while (ch<='9'&&ch>='0'){ x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }
    13     return x*f;
    14 }
    15 void update(int v){
    16     tree[v]=tree[v<<1]+tree[v<<1|1];
    17     flag[v]=flag[v<<1]&flag[v<<1|1];
    18 }
    19 void build(int v,int l,int r){
    20     if (l==r){
    21         tree[v]=a[l];
    22         if (a[l]<=1) flag[v]=1;
    23         return;
    24     }
    25     int mid=(l+r)>>1;
    26     build(v<<1,l,mid);
    27     build(v<<1|1,mid+1,r);
    28     update(v);
    29 } 
    30 ll query(int v,int l,int r,int x,int y){
    31     if (x<=l&&y>=r) return tree[v];
    32     int mid=(l+r)>>1;
    33     if (y<=mid) return query(v<<1,l,mid,x,y); else
    34     if (x>mid) return query(v<<1|1,mid+1,r,x,y); else
    35     return query(v<<1,l,mid,x,mid)+query(v<<1|1,mid+1,r,mid+1,y);
    36 }
    37 void change(int v,int l,int r,int x,int y){
    38     if (x<=l&&y>=r&&flag[v]) return;
    39     if (l==r){
    40         tree[v]=(ll)sqrt(tree[v]);
    41         if (tree[v]<=1) flag[v]=1;
    42         return;
    43     }
    44     int mid=(l+r)>>1;
    45     if (y<=mid) change(v<<1,l,mid,x,y); else
    46     if (x>mid) change(v<<1|1,mid+1,r,x,y); else{
    47         change(v<<1,l,mid,x,mid);
    48         change(v<<1|1,mid+1,r,mid+1,y); 
    49     }
    50     update(v);
    51 }
    52 int main(){
    53     n=read();
    54     for (int i=1;i<=n;i++) a[i]=read();
    55     build(1,1,n);
    56     m=read();
    57     for (int i=1;i<=m;i++){
    58         int x=read(),l=read(),r=read();
    59         if (x==1) printf("%lld
    ",query(1,1,n,l,r));
    60             else change(1,1,n,l,r);
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    使用QTM 博客客户端
    sdut 2080 最长公共子序列问题
    sdut 1730 数字三角形问题
    HDOJ 1905 Pseudoprime numbers(模运算)
    HDU 1285确定比赛名次(拓补排序)
    HDU 2094产生冠军(map)
    HDOJ 1228 A+B(map水题)
    HDOJ 1713 相遇周期 (最大公约数与最小公倍数)
    HDOJ 2098 分拆素数和(筛选法求素数)
    (转)最大子序列和问题
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7812801.html
Copyright © 2011-2022 走看看