zoukankan      html  css  js  c++  java
  • P4145 上帝造题的七分钟2 / 花神游历各国

    题目背景

    XLk觉得《上帝造题的七分钟》不太过瘾,于是有了第二部。

    题目描述

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

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

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

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

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

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

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

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

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

    输入输出格式

    输入格式:

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

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

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

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

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

    数据中有可能 l>rl>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%的数据, 1≤n,m≤1000,数列中的数不超过 32767

    对于100%的数据, 1≤n,m≤100000,数列中的数大于 0 ,且不超过 1012

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

    Solution:

      本题不要想得太难。(我开始竟然想去写~暴力分块~手动滑稽~

      首先,不难发现$10^{12}$不停开根号,最多$6$次会变为$1$。

      于是我们可以建一棵线段树,维护区间和与区间最大值:区间和是询问要用,就不解释了 ; 至于区间最大值可以用来大大优化复杂度,每次修改时若当前区间的最大值不大于$1$,则不需要修改。

    代码:

    #include<bits/stdc++.h>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    #define ll long long
    #define il inline
    using namespace std;
    const int N=1e5+7;
    ll n,m,a[N],sum[N*3],maxn[N*3];
    il ll gi(){
        ll a=0;char x=getchar();
        while(x<'0'||x>'9')x=getchar();
        while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
        return a;
    }
    il void pushup(int rt){
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]);
    }
    il void build(int l,int r,int rt){
        if(l==r){
            sum[rt]=maxn[rt]=a[l];
            return;
        }
        int m=l+r>>1;
        build(lson);build(rson);
        pushup(rt);
    }
    il void update(int L,int R,int l,int r,int rt){
        if(l==r){sum[rt]=maxn[rt]=sqrt(sum[rt]);return;}
        int m=l+r>>1;
        if(L<=m&&maxn[rt<<1]>1)update(L,R,lson);
        if(R>m&&maxn[rt<<1|1]>1)update(L,R,rson);
        pushup(rt);
    }
    il ll query(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r)return sum[rt];
        int m=l+r>>1;
        ll ret=0;
        if(L<=m)ret+=query(L,R,lson);
        if(R>m)ret+=query(L,R,rson);
        return ret;
    }
    int main(){
        n=gi();
        For(i,1,n)a[i]=gi();
        build(1,n,1);
        m=gi();
        int f,x,y;
        while(m--){
            f=gi(),x=gi(),y=gi();
            if(x>y)swap(x,y);
            if(f)printf("%lld
    ",query(x,y,1,n,1));
            else update(x,y,1,n,1);
        }
        return 0;
    }

     

  • 相关阅读:
    153. Find Minimum in Rotated Sorted Array
    228. Summary Ranges
    665. Non-decreasing Array
    661. Image Smoother
    643. Maximum Average Subarray I
    4.7作业
    面向对象编程
    常用模块3
    3.31作业
    常用模块2
  • 原文地址:https://www.cnblogs.com/five20/p/9053433.html
Copyright © 2011-2022 走看看