zoukankan      html  css  js  c++  java
  • HDU 5828 Rikka with Sequence(线段树区间加开根求和)

    Problem Description
    As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

    Yuta has an array A with n numbers. Then he makes m operations on it.

    There are three type of operations:

    1 l r x : For each i in [l,r], change A[i] to A[i]+x
    2 l r : For each i in [l,r], change A[i] to ⌊√A[i]⌋
    3 l r : Yuta wants Rikka to sum up A[i] for all i in [l,r]

    It is too difficult for Rikka. Can you help her?

    Input
    The first line contains a number t(1<=t<=100), the number of the testcases. And there are no more than 5 testcases with n>1000.

    For each testcase, the first line contains two numbers n,m(1<=n,m<=100000). The second line contains n numbers A[1]~A[n]. Then m lines follow, each line describe an operation.

    It is guaranteed that 1<=A[i],x<=100000.

    Output
    For each operation of type 3, print a lines contains one number -- the answer of the query.

    Sample Input
    1
    5 5
    1 2 3 4 5
    1 3 5 2
    2 1 4
    3 2 4
    2 3 5
    3 1 5

    Sample Output
    5
    6

    题意

    实现区间加,区间开根,区间求和

    题解

    一开始以为可以暴力开根,然后统计区间内是否全为1,后来发现开完根再加又可以开根所以单次复杂度就变成O(n)

     后来发现区间开根会出现一大片相同的区域,所以可以再维护一个最大最小值,如果maxx[rt]-minn[rt]==(LL)sqrt(maxx[rt])-(LL)sqrt(minn[rt])||maxx[rt]==minn[rt]就说明区间开根后所有值都相同,那就可以直接更新区间

    代码

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define LL long long
      5 
      6 const int maxn=1e5+5;
      7 
      8 LL sum[maxn<<2],lazy[maxn<<2],minn[maxn<<2],maxx[maxn<<2];
      9 
     10 void pushdown(int l,int r,int rt)
     11 {
     12     if(lazy[rt]==0)return;
     13     lazy[rt<<1]+=lazy[rt];
     14     lazy[rt<<1|1]+=lazy[rt];
     15     int mid=(l+r)>>1;
     16     sum[rt<<1]+=lazy[rt]*(mid-l+1);
     17     sum[rt<<1|1]+=lazy[rt]*(r-mid);
     18     maxx[rt<<1]+=lazy[rt];
     19     maxx[rt<<1|1]+=lazy[rt];
     20     minn[rt<<1]+=lazy[rt];
     21     minn[rt<<1|1]+=lazy[rt];
     22     lazy[rt]=0;
     23 }
     24 void pushup(int rt)
     25 {
     26     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
     27     minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);
     28     maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);
     29 }
     30 void build(int l,int r,int rt)
     31 {
     32     lazy[rt]=0;
     33     if(l==r)
     34     {
     35         scanf("%lld",&sum[rt]);
     36         minn[rt]=maxx[rt]=sum[rt];
     37         return;
     38     }
     39     int mid=(l+r)>>1;
     40     build(l,mid,rt<<1);
     41     build(mid+1,r,rt<<1|1);
     42     pushup(rt);
     43 }
     44 void update(int L,int R,LL C,int l,int r,int rt)
     45 {
     46     if(L<=l&&r<=R)
     47     {
     48         lazy[rt]+=C;
     49         sum[rt]+=(r-l+1)*C;
     50         maxx[rt]+=C;
     51         minn[rt]+=C;
     52         return;
     53     }
     54     int mid=(l+r)>>1;
     55     pushdown(l,r,rt);
     56     if(L<=mid)update(L,R,C,l,mid,rt<<1);
     57     if(R>mid)update(L,R,C,mid+1,r,rt<<1|1);
     58     pushup(rt);
     59 }
     60 void Sqrt(int L,int R,int l,int r,int rt)
     61 {
     62     if(L<=l&&r<=R)
     63     {
     64         if(maxx[rt]-minn[rt]==(LL)sqrt(maxx[rt])-(LL)sqrt(minn[rt])||maxx[rt]==minn[rt])
     65         {
     66             LL z=(LL)sqrt(maxx[rt])-maxx[rt];
     67             sum[rt]+=z*(r-l+1);
     68             maxx[rt]+=z,minn[rt]+=z,lazy[rt]+=z;
     69             return;
     70         }
     71     }
     72     int mid=(l+r)>>1;
     73     pushdown(l,r,rt);
     74     if(L<=mid)Sqrt(L,R,l,mid,rt<<1);
     75     if(R>mid)Sqrt(L,R,mid+1,r,rt<<1|1);
     76     pushup(rt);
     77 }
     78 LL query(int L,int R,int l,int r,int rt)
     79 {
     80     if(L<=l&&r<=R)
     81         return sum[rt];
     82     int mid=(l+r)>>1;
     83     LL ans=0;
     84     pushdown(l,r,rt);
     85     if(L<=mid)ans+=query(L,R,l,mid,rt<<1);
     86     if(R>mid)ans+=query(L,R,mid+1,r,rt<<1|1);
     87     pushup(rt);
     88     return ans;
     89 }
     90 int main()
     91 {
     92     int t,n,m;
     93     scanf("%d",&t);
     94     while(t--)
     95     {
     96         scanf("%d%d",&n,&m);
     97         build(1,n,1);
     98         for(int i=0;i<m;i++)
     99         {
    100             int op,l,r;
    101             LL x;
    102             scanf("%d%d%d",&op,&l,&r);
    103             if(op==1)
    104             {
    105                 scanf("%lld",&x);
    106                 update(l,r,x,1,n,1);
    107             }
    108             else if(op==2)
    109             {
    110                 Sqrt(l,r,1,n,1);
    111             }
    112             else if(op==3)
    113             {
    114                 printf("%lld
    ",query(l,r,1,n,1));
    115             }
    116         }
    117     }
    118     return 0;
    119 }
    120 /*
    121 1
    122 5 10
    123 1 2 3 4 5
    124 1 1 3 10
    125 2 1 3
    126 2 1 3
    127 2 1 3
    128 2 1 3
    129 3 1 3
    130 */
  • 相关阅读:
    Salesforce和SAP Netweaver里数据库表的元数据设计
    Salesforce平台支持多租户Multi tenant的核心设计思路
    S/4HANA生产订单增强WORKORDER_UPDATE方法BEFORE_UPDATE参数分析
    S/4HANA生产订单的标准状态和透明工厂原型状态的映射
    1048. Find Coins (25)
    1101. Quick Sort (25)
    1009. Product of Polynomials (25)
    pta 奇数值结点链表&&单链表结点删除
    1007. Maximum Subsequence Sum (25)
    1006. Sign In and Sign Out (25)
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/9842379.html
Copyright © 2011-2022 走看看