• uoj#228 基础数据结构练习题


    题面:http://uoj.ac/problem/228

    正解:线段树。

    我们可以发现,开根号时一个区间中的数总是趋近相等。判断一个区间的数是否相等,只要判断最大值和最小值是否相等就行了。如果这个区间的数相等,那么他们开方的数也相等,我们直接转化为减去一个数就行了。

    但是这是没有办法$AC$的,我们还要加一个特判,就是最大值与最小值差为$1$,且他们开方以后的差也为$1$,如$8$和$9$这两个数,这样就能通过所有数据了。复杂度证明?我不会。。

      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <complex>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <cstdio>
      8 #include <vector>
      9 #include <cmath>
     10 #include <queue>
     11 #include <stack>
     12 #include <map>
     13 #include <set>
     14 #define ls (x<<1)
     15 #define rs (x<<1|1)
     16 #define N (100010)
     17 #define il inline
     18 #define RG register
     19 #define ll long long
     20 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
     21 
     22 using namespace std;
     23 
     24 ll lazy[4*N],sum[4*N],mx[4*N],mn[4*N],a[N],n,m;
     25 
     26 il ll gi(){
     27     RG ll x=0,q=1; RG char ch=getchar();
     28     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     29     if (ch=='-') q=-1,ch=getchar();
     30     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     31     return q*x;
     32 }
     33 
     34 il void add(RG ll x,RG ll l,RG ll r,RG ll v){
     35     sum[x]+=(r-l+1)*v,mx[x]+=v,mn[x]+=v,lazy[x]+=v; return;
     36 }
     37 
     38 il void merge(RG ll x,RG ll l,RG ll r){
     39     sum[x]=sum[ls]+sum[rs]+(r-l+1)*lazy[x];
     40     mx[x]=max(mx[ls],mx[rs])+lazy[x];
     41     mn[x]=min(mn[ls],mn[rs])+lazy[x];
     42     return;
     43 }
     44 
     45 il void build(RG ll x,RG ll l,RG ll r){
     46     if (l==r){ sum[x]=mx[x]=mn[x]=a[l]; return; }
     47     RG ll mid=(l+r)>>1;
     48     build(ls,l,mid),build(rs,mid+1,r);
     49     merge(x,l,r); return;
     50 }
     51 
     52 il void update(RG ll x,RG ll l,RG ll r,RG ll xl,RG ll xr,RG ll v){
     53     if (xl<=l && r<=xr){ add(x,l,r,v); return; } RG ll mid=(l+r)>>1;
     54     if (xr<=mid) update(ls,l,mid,xl,xr,v);
     55     else if (xl>mid) update(rs,mid+1,r,xl,xr,v);
     56     else update(ls,l,mid,xl,mid,v),update(rs,mid+1,r,mid+1,xr,v);
     57     merge(x,l,r); return;
     58 }
     59 
     60 il void Sqrt(RG ll x,RG ll l,RG ll r,RG ll xl,RG ll xr,RG ll la){
     61     if (xl<=l && r<=xr){
     62     if (mn[x]==mx[x]){
     63         RG ll del=mx[x]+la-(ll)sqrt(mx[x]+la);
     64         add(x,l,r,-del); return;
     65     } else{
     66         RG ll s1=(ll)sqrt(mn[x]+la),s2=(ll)sqrt(mx[x]+la);
     67         if (mn[x]+1==mx[x] && s1+1==s2){
     68         RG ll del=mx[x]+la-s2;
     69         add(x,l,r,-del); return;
     70         }
     71     }
     72     }
     73     RG ll mid=(l+r)>>1; la+=lazy[x];
     74     if (xr<=mid) Sqrt(ls,l,mid,xl,xr,la);
     75     else if (xl>mid) Sqrt(rs,mid+1,r,xl,xr,la);
     76     else Sqrt(ls,l,mid,xl,mid,la),Sqrt(rs,mid+1,r,mid+1,xr,la);
     77     merge(x,l,r); return;
     78 }
     79 
     80 il ll query(RG ll x,RG ll l,RG ll r,RG ll xl,RG ll xr,RG ll la){
     81     if (xl<=l && r<=xr) return sum[x]+(r-l+1)*la;
     82     RG ll mid=(l+r)>>1; la+=lazy[x];
     83     if (xr<=mid) return query(ls,l,mid,xl,xr,la);
     84     else if (xl>mid) return query(rs,mid+1,r,xl,xr,la);
     85     else return query(ls,l,mid,xl,mid,la)+query(rs,mid+1,r,mid+1,xr,la);
     86 }
     87 
     88 il void work(){
     89     n=gi(),m=gi(); for (RG ll i=1;i<=n;++i) a[i]=gi(); build(1,1,n);
     90     for (RG ll i=1,type,l,r,x;i<=m;++i){
     91     type=gi();
     92     if (type==1) l=gi(),r=gi(),x=gi(),update(1,1,n,l,r,x);
     93     if (type==2) l=gi(),r=gi(),Sqrt(1,1,n,l,r,0);
     94     if (type==3) l=gi(),r=gi(),printf("%lld
    ",query(1,1,n,l,r,0));
     95     }
     96     return;
     97 }
     98 
     99 int main(){
    100     File("standard");
    101     work();
    102     return 0;
    103 }
  • 相关阅读:
    Spring中文文档
    学装饰器之前必须要了解的四点
    三元运算符
    functools 中的 reduce 函数基本写法
    filter 函数基本写法
    map 函数基本写法
    迭代器和可迭代对象区别
    斐波那契数列进一步讨论性能
    无论传入什么数据都转换为列表
    将每一个分隔开的字符的首字母大写
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6652882.html
Copyright © 2020-2023  润新知