zoukankan      html  css  js  c++  java
  • UOJ228 基础数据结构练习题

    题面:由于Paste下来太鬼,删了。

    这题其实应该叫数据结构练习题。。。。

    WFJ大佬上午推荐了这道题,我就去做一做,然后一天就过去了。。。。

    这里多了一个开根号的操作。。。变得很棘手

    但其实可以发现这里面数的差会越来越小,当一个区间里所有数都一样时,开根号操作就可以转化成区间减去一个数a-sqrt(a)了。

    所有数都一样,可转化为max==min判断。

    然而有一个奇怪的优化。。。

    如果min和max的差为1,且√max=√min+1,就可以优化。。。

    然后就A了。。。

     1 // It is made by XZZ
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 using namespace std;
     6 #define rep(a,b,c) for(rg int a=b;a<=c;a++)
     7 #define drep(a,b,c) for(rg int a=b;a>=c;a--)
     8 #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
     9 #define il inline
    10 #define rg register
    11 #define vd void
    12 #define ls ((id)<<1)
    13 #define rs ((id)<<1|1)
    14 #define mid ((l+r)>>1)
    15 typedef long long ll;
    16 il int gi(){
    17     rg int x=0,f=1;rg char ch=getchar();
    18     while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
    19     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    20     return x*f;
    21 }
    22 const int maxn=100001;
    23 int L[maxn<<2],R[maxn<<2];
    24 ll num[maxn<<2],Max[maxn<<2],Min[maxn<<2],lazy[maxn<<2];
    25 
    26 il vd build(int l,int r,int id){
    27     L[id]=l,R[id]=r;
    28     if(l==r)num[id]=Max[id]=Min[id]=(ll)gi();
    29     else build(l,mid,ls),build(mid+1,r,rs),num[id]=num[ls]+num[rs],Max[id]=max(Max[ls],Max[rs]),Min[id]=min(Min[ls],Min[rs]);
    30 }
    31 
    32 il vd down(int id){
    33     if(L[id]==R[id])return;
    34     num[ls]+=lazy[id]*(R[ls]-L[ls]+1);
    35     if(L[ls]-R[ls])Max[ls]+=lazy[id],Min[ls]+=lazy[id];
    36     else Max[ls]=Min[ls]=num[ls];
    37     lazy[ls]+=lazy[id];
    38     num[rs]+=lazy[id]*(R[rs]-L[rs]+1);
    39     if(L[rs]-R[rs])Max[rs]+=lazy[id],Min[rs]+=lazy[id];
    40     else Max[rs]=Min[rs]=num[rs];
    41     lazy[rs]+=lazy[id];
    42     lazy[id]=0;
    43 }
    44 
    45 il vd update_add(int id,int l,int r,ll Num){
    46     down(id);
    47     if(L[id]>=l&&R[id]<=r){num[id]+=Num*(R[id]-L[id]+1),Max[id]+=Num,Min[id]+=Num,lazy[id]=Num;return;}
    48     if(R[ls]>=l)update_add(ls,l,r,Num);
    49     if(L[rs]<=r)update_add(rs,l,r,Num);
    50     num[id]=num[ls]+num[rs],Max[id]=max(Max[ls],Max[rs]),Min[id]=min(Min[ls],Min[rs]);
    51 }
    52 
    53 il vd update_sqrt(int id,int l,int r){
    54     down(id);
    55     if((L[id]>=l&&R[id]<=r)&&(Max[id]==Min[id]||(Max[id]==Min[id]+1&&(ll)sqrt(Max[id])==(ll)sqrt(Min[id])+1))){update_add(id,l,r,(ll)sqrt(Max[id])-Max[id]);return;}
    56     if(R[ls]>=l)update_sqrt(ls,l,r);
    57     if(L[rs]<=r)update_sqrt(rs,l,r);
    58     num[id]=num[ls]+num[rs],Max[id]=max(Max[ls],Max[rs]),Min[id]=min(Min[ls],Min[rs]);
    59 }
    60 
    61 il ll query(int id,int l,int r){
    62     down(id);
    63     if(L[id]>=l&&R[id]<=r)return num[id];
    64     if(R[ls]<l)return query(rs,l,r);
    65     else if(L[rs]>r)return query(ls,l,r);
    66     else return query(ls,l,r)+query(rs,l,r);
    67 }
    68 
    69 int main(){
    70     rg int n=gi(),m=gi();
    71     build(1,n,1);
    72     rg int k,l,r;
    73     while(m--){
    74     k=gi(),l=gi(),r=gi();
    75     switch(k){
    76     case 1:update_add(1,l,r,(ll)gi());break;
    77     case 2:update_sqrt(1,l,r);break;
    78     case 3:printf("%lld
    ",query(1,l,r));break;
    79     }
    80     }
    81     return 0;
    82 }
    View Code

    PS.好久没打线段树了。。。

  • 相关阅读:
    Echarts——一个简单的嵌套饼图
    Gephi——使用map of countries和Geo Layout实现包含地理坐标的数据可视化
    PMP知识点(五)——资源管理表示方法
    Python——LOL官方商城皮肤信息爬取(一次练手)
    Python——一个简单的进度条的实现
    Python——阶段总结(一)
    PMP知识点(六)——项目经理权利类型
    PMP知识点(五)——配置管理
    Python——使用高德API获取指定城指定类别POI并实现XLSX文件合并
    PMP知识点(一)——风险登记册
  • 原文地址:https://www.cnblogs.com/xzz_233/p/7230131.html
Copyright © 2011-2022 走看看