• BZOJ 3211: 花神游历各国【线段树区间开方问题】


    3211: 花神游历各国

    Time Limit: 5 Sec  Memory Limit: 128 MB
    Submit: 3514  Solved: 1306
    [Submit][Status][Discuss]

    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 数据已加强

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3211

    分析:

    题目这么长,其实就是2个操作:

    1.询问L,R中的各个数之和

    2.将L,R中的每个数x,将x修x1/2,向下取整。。

    我们其实可以发现1000000000中的数修改不了几次就会变成1,那么直接暴力修改,若一段区间内的数全部<=1也就不用再改下去了。

    下面给出AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 inline int read()
     4 {
     5     int x=0,f=1;
     6     char ch=getchar();
     7     while(ch<'0'||ch>'9')
     8     {
     9         if(ch=='-')
    10             f=-1;
    11         ch=getchar();
    12     }
    13     while(ch>='0'&&ch<='9')
    14     {
    15         x=x*10+ch-'0';
    16         ch=getchar();
    17     }
    18     return x*f;
    19 }
    20 const int N=100010;
    21 int n,m,pos,x,y;
    22 int a[N],add[N<<2];
    23 typedef long long ll;
    24 ll ans,sum[N<<2];
    25 inline void buildtree(int l,int r,int pos)
    26 {
    27     if(l==r)
    28     {
    29         sum[pos]=a[l];
    30         if(a[l]<=1)
    31             add[pos]=1;
    32         else
    33             add[pos]=0;
    34         return;
    35     }
    36     int mid=(l+r)/2;
    37     buildtree(l,mid,pos*2);
    38     buildtree(mid+1,r,pos*2+1);
    39     sum[pos]=sum[pos*2]+sum[pos*2+1];
    40     add[pos]=add[pos*2]&add[pos*2+1];
    41 }
    42 inline void update(int l,int r,int x,int y,int pos)
    43 {
    44     if(add[pos])
    45         return;
    46     if(l==r)
    47     {
    48         sum[pos]=(int)sqrt(sum[pos]);
    49         if(sum[pos]<=1)
    50             add[pos]=1;
    51         return;
    52     }
    53     int mid=(l+r)/2;
    54     if(x<=mid)
    55         update(l,mid,x,y,pos*2);
    56     if(y>mid)
    57         update(mid+1,r,x,y,pos*2+1);
    58     add[pos]=add[pos*2]&add[pos*2+1];
    59     sum[pos]=sum[pos*2]+sum[pos*2+1];
    60 }
    61 inline void solve(int l,int r,int x,int y,int pos)
    62 {
    63     if(x<=l&&r<=y)
    64     {
    65         ans+=sum[pos];
    66         return;
    67     }
    68     int mid=(l+r)/2;
    69     if(x<=mid)
    70         solve(l,mid,x,y,pos*2);
    71     if(y>mid)
    72         solve(mid+1,r,x,y,pos*2+1);
    73 }
    74 int main()
    75 {
    76     n=read();
    77     for(int i=1;i<=n;i++)
    78         a[i]=read();
    79     buildtree(1,n,1);
    80     m=read();
    81     for(int i=1;i<=m;i++)
    82     {
    83         pos=read();
    84         x=read();
    85         y=read();
    86         if(pos==1)
    87         {
    88             ans=0;
    89             solve(1,n,x,y,1);
    90             printf("%lld
    ",ans);
    91         }
    92         else
    93             update(1,n,x,y,1);
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    [BZOJ3745][Coci2015]Norma
    [OJ#15]TR #2 画心
    [BZOJ3585][BZOJ3339]mex
    [OJ#63]树句节够提
    [LOJ#2255][BZOJ5017][Snoi2017]炸弹
    [LOJ#525]「LibreOJ β Round #4」多项式
    【字符编码】Java字符编码详细解答及问题探讨
    【Java基础】序列化与反序列化深入分析
    【目录】JVM目录
    【知识积累】随机数生成的几种方法
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/7305431.html
Copyright © 2020-2023  润新知