zoukankan      html  css  js  c++  java
  • BZOJ 3038上帝造题的七分钟2

    题面:

    3038: 上帝造题的七分钟2

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 1450  Solved: 620
    [Submit][Status][Discuss]

    Description

    XLk觉得《上帝造题的七分钟》不太过瘾,于是有了第二部。
    "第一分钟,X说,要有数列,于是便给定了一个正整数数列。
    第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作。
    第三分钟,k说,要能查询,于是便有了求一段数的和的操作。
    第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围。
    第五分钟,诗人说,要有韵律,于是便有了时间限制和内存限制。
    第六分钟,和雪说,要省点事,于是便有了保证运算过程中及最终结果均不超过64位有符号整数类型的表示范围的限制。
    第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。"
    ——《上帝造题的七分钟·第二部》
    所以这个神圣的任务就交给你了。

    Input

    第一行一个整数n,代表数列中数的个数。
    第二行n个正整数,表示初始状态下数列中的数。
    第三行一个整数m,表示有m次操作。
    接下来m行每行三个整数k,l,r,k=0表示给[l,r]中的每个数开平方(下取整),k=1表示询问[l,r]中各个数的和。

    Output

    对于询问操作,每行输出一个回答。

    Sample Input

    10
    1 2 3 4 5 6 7 8 9 10
    5
    0 1 10
    1 1 10
    1 1 5
    0 5 8
    1 4 8

    Sample Output

    19
    7
    6

    HINT

    1:对于100%的数据,1<=n<=100000,1<=l<=r<=n,数列中的数大于0,且不超过1e12。

    2:数据不保证L<=R 若L>R,请自行交换L,R,谢谢!

    可以发现,数列中的数至多经过6次开根就会变成1。

    对每块打上标记,记录是否全变成1。

    若是,那就不用再更新下去。

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<math.h>
     4 using namespace std;
     5 #define maxn 100001
     6 #define LL long long
     7 LL a[maxn],s[maxn];
     8 int pos[maxn];
     9 bool flag[maxn];
    10 int n,m,len;
    11 void pushup(int x)
    12 {
    13     if(flag[x]==true)
    14         return ;
    15     flag[x]=true;
    16     s[x]=0;
    17     int l=(x-1)*len+1,r=min(x*len,n);
    18     for(int i=l;i<=r;i++)
    19     {
    20         a[i]=sqrt(a[i]);
    21         s[x]+=a[i];
    22         if(s[x]>(r-l+1))
    23             flag[x]=false;
    24     }
    25 }
    26 void update(int l,int r)
    27 {
    28     if(pos[l]==pos[r])
    29     {
    30         for(int i=l;i<=r;i++)
    31         {
    32             s[pos[l]]-=a[i];
    33             a[i]=sqrt(a[i]);
    34             s[pos[l]]+=a[i];        
    35         }
    36     }
    37     else
    38     {
    39         int L=pos[l]*len,R=(pos[r]-1)*len+1;
    40         for(int i=l;i<=L;i++)
    41         {
    42             s[pos[l]]-=a[i];
    43             a[i]=sqrt(a[i]);
    44             s[pos[l]]+=a[i];
    45         }
    46         for(int i=R;i<=r;i++)
    47         {
    48             s[pos[r]]-=a[i];
    49             a[i]=sqrt(a[i]);
    50             s[pos[r]]+=a[i];
    51         }
    52         for(int i=pos[l]+1;i<=pos[r]-1;i++)
    53             pushup(i);
    54     }
    55 }
    56 LL query(int l,int r)
    57 {
    58     LL ans=0;
    59     if(pos[l]==pos[r])
    60     {
    61         for(int i=l;i<=r;i++)
    62             ans+=a[i];
    63     }
    64     else
    65     {
    66         int L=pos[l]*len,R=(pos[r]-1)*len+1;
    67         for(int i=l;i<=L;i++)
    68             ans+=a[i];
    69         for(int j=R;j<=r;j++)
    70             ans+=a[j];
    71         for(int i=pos[l]+1;i<pos[r];i++)
    72             ans+=s[i];
    73     }
    74     return ans;
    75 }
    76 int main()
    77 {
    78     int x,y,z;
    79     scanf("%d",&n);
    80     len=90;
    81     for(int i=1;i<=n;i++)
    82     {
    83         scanf("%lld",&a[i]);
    84         pos[i]=(i-1)/len+1;
    85         s[pos[i]]+=a[i];
    86     }
    87     scanf("%d",&m);
    88     for(int i=1;i<=m;i++)
    89     {
    90         scanf("%d%d%d",&x,&y,&z);
    91         if(y>z)
    92             y^=z^=y^=z;
    93         if(x==0)
    94             update(y,z);
    95         else
    96             printf("%lld
    ",query(y,z));
    97     }
    98 }
    BZOJ 3038
  • 相关阅读:
    在Android中,使用Kotlin的 API请求简易方法
    Android开发者的Kotlin:书
    用Kotlin开发Android应用(IV):定制视图和Android扩展
    用Kotlin开发Android应用(III):扩展函数和默认值
    zookeeper应用
    BigDecimal的setScale()方法无效(坑)
    Linux命令详解之—less命令
    jdk10 var定义变量的由来
    Mysql DataPacketTooBigException异常处理
    JDK自带的监控工具方法
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7163301.html
Copyright © 2011-2022 走看看