zoukankan      html  css  js  c++  java
  • HDU

      这题太坑了。。。满满的都是坑点

      1号坑点:给定左右区间有可能是反的。。。因为题目上说x,y之间,但是没有说明x,y的大小关系(害我一直RE到怀疑人生)

      2号坑点:开根号的和不等于和开根号(还好避开了)

      3号坑点:当你明白了2号坑,你就会选择。。。单点更新,然后你就T飞了。其实一个1e18的数,开不了几次根就没了。。。所以修改多的情况下,大部分数很快降到1,当一个区间内部全是1,你还用一个个单点更新吗?所以就在2的基础上,加上如果这个区间的值的集合等于区间长度,直接返回,里面肯定全是1,还更新个屁啊。

      4号坑点:当你觉得的自己稳了的时候,PE一发。。。末尾换行后再换行。。。WTF

      

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int maxn=100010;
    LL a[maxn];
    struct node{
       int l,r;
       LL val;
    }tree[maxn<<2];
    LL sum;
    inline int L(int r){return r<<1;};
    inline int R(int r){return r<<1|1;};
    inline int MID(int l,int r){return (l+r)>>1;};
    void buildtree(int root,int l,int r){
      tree[root].l=l;
      tree[root].r=r;
      tree[root].val=0;
      if (l==r){
        tree[root].val=a[l];
        return;
      }
      int mid=MID(l,r);
      buildtree(L(root),l,mid);
      buildtree(R(root),mid+1,r);
      tree[root].val=tree[L(root)].val+tree[R(root)].val;
    }
    void update(int root,int ul,int ur){
       int l=tree[root].l;
       int r=tree[root].r;
       if (tree[root].val==r-l+1){
          return;
       }
       if (l==r){
         tree[root].val=(LL)sqrt(tree[root].val);
         return;
       }
       int mid=MID(l,r);
       if (ur<=mid){
        update(L(root),ul,ur);
       }else if(ul>mid){
        update(R(root),ul,ur);
       }else {
        update(L(root),ul,mid);
        update(R(root),mid+1,ur);
       }
       tree[root].val=tree[L(root)].val+tree[R(root)].val;
    }
    void query(int root,int ql,int qr){
      int l=tree[root].l;
      int r=tree[root].r;
      if (ql<=l && r<=qr){
        sum+=tree[root].val;
        return;
      }
      int mid=MID(l,r);
      if(qr<=mid){
        query(L(root),ql,qr);
      }else if(ql>mid){
        query(R(root),ql,qr);
      }else {
        query(L(root),ql,mid);
        query(R(root),mid+1,qr);
      }
    }
    int main(){
      int n,m;
      int cas=1;
      while(~scanf("%d",&n)){
         printf("Case #%d:
    ",cas++);
         for (int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
         }
         buildtree(1,1,n);
         scanf("%d",&m);
         int tmp1,tmp2,tmp3;
         for (int i=1;i<=m;i++){
            scanf("%d%d%d",&tmp1,&tmp2,&tmp3);
            if (tmp2>tmp3){
                swap(tmp2,tmp3);
            }
            if(tmp1){
              sum=0;
              query(1,tmp2,tmp3);
              printf("%lld
    ",sum);
            }else{
              update(1,tmp2,tmp3);
            }
         }
         printf("
    ");
      }
      return 0;
    }
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    debian 中安装GIT
    多核处理器 利用多线程 加速 编译内核 速度
    ubuntu下安装中文输入法(乱码等问题)
    ubuntu 10.04源 更新源列表
    php empty,isset,is_null比较(差异与异同) Leone
    Win 7 各版本的含义 Leone
    Atitit DbServiceV4qb9 数据库查询类库v4 新特性
    Atitit 图像处理之仿油画效果 Oilpaint油画滤镜 水彩画 漫画滤镜 v2
    Atitit 多继承实现解决方案 java c#
    Atitit 基于图片图像 与文档混合文件夹的分类
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10345098.html
Copyright © 2011-2022 走看看