zoukankan      html  css  js  c++  java
  • SP2713 GSS4

    题目大意

    (n) 个数,和在(10^{18})范围内。

    也就是(sum~a_i~leq~10^{18})

    现在有两种操作

    0 x y 把区间[x,y]内的每个数开方,下取整

    1 x y 询问区间[x,y]的每个数的和

    格式: 有多组数据,数据以EOF结束,对于每组数据,输出数据的序号,每组数据之后输出一个空行。

    注意: 不保证给出的区间[x, y]有(x <= y),如果(x>y)请交换(x)(y)

    感谢@Edgration 提供的翻译

    输入输出格式

    输入格式:

    Multiple test cases, please proceed them one by one. Input terminates by EOF.

    For each test case:

    The first line contains an integer N. The following line contains N integers, representing the sequence A _{1}1​..A _{N}N​ .
    The third line contains an integer M. The next M lines contain the operations in the form "i x y".i=0 denotes the modify operation, i=1 denotes the query operation.

    输出格式:

    For each test case:

    Output the case number (counting from 1) in the first line of output. Then for each query, print an integer as the problem required.

    Print an blank line after each test case.

    See the sample output for more details.

    输入输出样例

    输入样例#1:

    5
    1 2 3 4 5
    5
    1 2 4
    0 2 4
    1 2 4
    0 4 5
    1 1 5
    4
    10 10 10 10
    3
    1 1 4
    0 2 3
    1 1 4
    

    输出样例#1:

    Case #1:
    9
    4
    6
    
    Case #2:
    40
    26
    

    思路:

    第一眼,一点头绪都没有,因为涉及到区间修改和查询,像线段树,但又一副不可做的样子,因为如果区间修改不加任何优化的话,常数就会大的一批,应该会超时,那么,我们就来考虑关于开方的有关性质,首先(sqrt(1)=1),震惊!!没错,这就是修改终点,如果一个位置的数为1,再开方是没有意义的,那么我们就可以维护一个区间最大值,如果这个区间最大值是(1),也就是这个区间的数都是(1),那么就没必要进行修改了,区间求和的话就跟普通线段树没什么区别了。还有,为什么区间修改时终点是(l==r)呢?难道不是(L<=l)&&(r<=R)么?因为这里的区间修改是采用了一种暴力的思想,也就是一个一个改,相当于单点修改。

    自己整理的题解

    如果不知道怎么写的话,可以参考以下代码:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #define maxn 100007
    #define ll long long
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    int n,m,tim;
    ll maxx[maxn<<2],sum[maxn<<2];
    inline ll qread() {
      char c=getchar();ll num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    inline void pushup(int rt) {
      sum[rt]=sum[ls]+sum[rs];
      maxx[rt]=max(maxx[ls],maxx[rs]);
    }
    void build(int rt, int l, int r) {
      if(l==r) {
        sum[rt]=maxx[rt]=qread();
        return;
      }
      int mid=(l+r)>>1;
      build(ls,l,mid);
      build(rs,mid+1,r);
      pushup(rt);
    }
    void modify(int rt, int l, int r, int L, int R) {
      if(l==r) {
        sum[rt]=sqrt(sum[rt]);
        maxx[rt]=sqrt(maxx[rt]);
        return;
      }
      int mid=(l+r)>>1;
      if(L<=mid&&maxx[ls]>1) modify(ls,l,mid,L,R);
      if(R>mid&&maxx[rs]>1) modify(rs,mid+1,r,L,R);
      pushup(rt);
    }
    ll csum(int rt, int l, int r, int L, int R) {
      if(L>r||R<l) return 0;
      if(L<=l&&r<=R) return sum[rt];
      int mid=(l+r)>>1;
      return csum(ls,l,mid,L,R)+csum(rs,mid+1,r,L,R);
    }
    int main() {
      while(scanf("%d",&n)==1) {
        printf("Case #%d:
    ",++tim);
        build(1,1,n);
        m=qread();
        for(int i=1,k,x,y;i<=m;++i) {
          k=qread(),x=qread(),y=qread();
          if(x>y) swap(x,y);
          if(!k) modify(1,1,n,x,y);
          else printf("%lld
    ",csum(1,1,n,x,y));  
        }
      }
      return 0;
    }
    
  • 相关阅读:
    PHP格式化时间戳函数分享
    The Mac App Store isn't working. How to fix?
    sqlite+ef+powertools
    部署node api的二三事
    node 写api几个简单的问题
    基于项目的简单的代码生成器
    h5跳转到app的实现
    几种常用的git命令
    发送post请求几种常见content-type类型
    cors(Cross-origin resource sharing)跨域资源共享
  • 原文地址:https://www.cnblogs.com/grcyh/p/10230717.html
Copyright © 2011-2022 走看看