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

    题目描述

    "第一分钟,X说,要有数列,于是便给定了一个正整数数列。

    第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作。

    第三分钟,k说,要能查询,于是便有了求一段数的和的操作。

    第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围。

    第五分钟,诗人说,要有韵律,于是便有了时间限制和内存限制。

    第六分钟,和雪说,要省点事,于是便有了保证运算过程中及最终结果均不超过64位有符号整数类型的表示范围的限制。

    第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。"

    ——《上帝造题的七分钟·第二部》

    所以这个神圣的任务就交给你了。

    输入输出格式

    输入格式:

    第一行一个整数 nn ,代表数列中数的个数。

    第二行 nn 个正整数,表示初始状态下数列中的数。

    第三行一个整数 mm ,表示有 mm 次操作。

    接下来 mm 行每行三个整数k,l,r

    • k=0表示给 [l,r][l,r] 中的每个数开平方(下取整)
    • k=1表示询问 [l,r][l,r] 中各个数的和。

    数据中有可能 l>rl>r ,所以遇到这种情况请交换l和r。

    输出格式:

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

    输入输出样例

    输入样例#1
    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
    输出样例#1
    19
    7
    6

    说明

    对于30%的数据, 1le n,mle 10001n,m1000 ,数列中的数不超过 3276732767 。

    对于100%的数据, 1 le n,m le 1000001n,m100000 , 1 le l,r le n1l,rn ,数列中的数大于 00 ,且不超过 10^{12}1012 。

    注意l有可能大于r,遇到这种情况请交换l,r。

    一道线段树的题目。

    首先我们考虑一下,一个小于等于10^12的数,开了6次方之后就已经等于1了(可以自己拿计算器算一下)。而对于1,再开方也没有意义。也就是说,对每一个数,总共的开方次数只有6*n。所以我们可以开一个线段树,对于每一个修改操作,暴力修改。如果某区间的最大值为1,则跳过此区间的修改。最后基本上就是模板了

     1 //minamoto
     2 #include<bits/stdc++.h>
     3 #define ll long long
     4 #define rint register int
     5 using namespace std;
     6 const int N=400005;
     7 int n,m;ll a[N],sum[N],maxn[N];
     8 void pushup(int p){
     9     sum[p]=sum[p<<1]+sum[p<<1|1];
    10     maxn[p]=max(maxn[p<<1],maxn[p<<1|1]);
    11 }
    12 void build(int p,int l,int r){
    13     if(l==r){
    14         sum[p]=maxn[p]=a[l];return;
    15     }
    16     int mid=(l+r)>>1;
    17     build(p<<1,l,mid);
    18     build(p<<1|1,mid+1,r);
    19     pushup(p);
    20 }
    21 void change(int p,int l,int r,int ql,int qr){
    22     if(l==r){
    23         sum[p]=sqrt(sum[p]),maxn[p]=sqrt(maxn[p]);return;
    24     }
    25     int mid=(l+r)>>1;
    26     if(ql<=mid&&maxn[p<<1]>1) change(p<<1,l,mid,ql,qr);
    27     if(qr>mid&&maxn[p<<1|1]>1) change(p<<1|1,mid+1,r,ql,qr);
    28     pushup(p);
    29 }
    30 ll query(int p,int l,int r,int ql,int qr){
    31     if(ql<=l&&qr>=r) return sum[p];
    32     int mid=(l+r)>>1;
    33     ll res=0;
    34     if(ql<=mid) res+=query(p<<1,l,mid,ql,qr);
    35     if(qr>mid) res+=query(p<<1|1,mid+1,r,ql,qr);
    36     return res;
    37 }
    38 int main(){
    39     scanf("%d",&n);
    40     for(rint i=1;i<=n;++i) scanf("%lld",&a[i]);
    41     build(1,1,n);
    42     scanf("%d",&m);
    43     while(m--){
    44         int opt,l,r;
    45         scanf("%d%d%d",&opt,&l,&r);
    46         if(l>r) swap(l,r);
    47         if(opt==0) change(1,1,n,l,r);
    48         else printf("%lld
    ",query(1,1,n,l,r));
    49     }
    50     return 0;
    51 }
    深深地明白自己的弱小
  • 相关阅读:
    Oracle第五周测验
    软件测试第五周
    Oracle第四周作业
    c++第二章测试
    软件测试第四章
    软件测试 第三章
    Centos 安装.NET Core环境
    .net core 集成极光推送
    Swagger添加文件上传测试
    linux firewall
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9318313.html
Copyright © 2011-2022 走看看