• BZOJ3211:花神游历各国(线段树)


    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

    Solution

    一个数最多只会被开根$loglog$次(因为每次开根相当于指数除$2$)。

    然后用线段树维护一个区间和和区间最大值,如果这个区间的最大值小于等于$1$就没有做的必要了。

    去年这个题写了个分块在$BZOJ$被卡了之后就扔着不管了……

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #define N (100009)
     6 #define LL long long
     7 using namespace std;
     8 
     9 struct Sgt{LL max,sum;}Segt[N<<2];
    10 int n,m,a[N],opt,x,y;
    11 
    12 inline int read()
    13 {
    14     int x=0,w=1; char c=getchar();
    15     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
    16     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
    17     return x*w;
    18 }
    19 
    20 void Build(int now,int l,int r)
    21 {
    22     if (l==r) {Segt[now].max=a[l]; Segt[now].sum=a[l]; return;}
    23     int mid=(l+r)>>1;
    24     Build(now<<1,l,mid); Build(now<<1|1,mid+1,r);
    25     Segt[now].sum=Segt[now<<1].sum+Segt[now<<1|1].sum;
    26     Segt[now].max=max(Segt[now<<1].max,Segt[now<<1|1].max);
    27 }
    28 
    29 void Update(int now,int l,int r,int l1,int r1)
    30 {
    31     if (Segt[now].max<=1 || l>r1 || r<l1) return;
    32     if (l==r) {Segt[now].max=Segt[now].sum=sqrt(Segt[now].sum); return;}
    33     int mid=(l+r)>>1;
    34     Update(now<<1,l,mid,l1,r1); Update(now<<1|1,mid+1,r,l1,r1);
    35     Segt[now].sum=Segt[now<<1].sum+Segt[now<<1|1].sum;
    36     Segt[now].max=max(Segt[now<<1].max,Segt[now<<1|1].max);
    37 }
    38 
    39 LL Query(int now,int l,int r,int l1,int r1)
    40 {
    41     if (l>r1 || r<l1) return 0;
    42     if (l1<=l && r<=r1) return Segt[now].sum;
    43     int mid=(l+r)>>1;
    44     return Query(now<<1,l,mid,l1,r1)+Query(now<<1|1,mid+1,r,l1,r1);
    45 }
    46 
    47 int main()
    48 {
    49     n=read();
    50     for (int i=1; i<=n; ++i) a[i]=read();
    51     Build(1,1,n);
    52     m=read();
    53     while (m--)
    54     {
    55         opt=read(); x=read(); y=read();
    56         if (opt==1) printf("%lld
    ",Query(1,1,n,x,y));
    57         else Update(1,1,n,x,y);
    58     }
    59 }
  • 相关阅读:
    【Java并发编程】:使用synchronized获取互斥锁
    【Java并发编程】:Runnable和Thread实现多线程的区别
    【Java并发编程】:volatile变量修饰符
    【Java并发编程】:守护线程与线程阻塞的四种情况
    【Java并发编程】:线程挂起、恢复与终止
    【Java并发编程】:线程中断
    redis配置详细解析
    redis常用命令
    centos7上安装redis
    redis简介
  • 原文地址:https://www.cnblogs.com/refun/p/10361888.html
Copyright © 2020-2023  润新知