zoukankan      html  css  js  c++  java
  • HDU

    题目链接

    三种操作:区间加,区间开根号,区间求和。

    修改的时候判断区间内的最大值和最小值是否相等或者差1,如果相等则变为区间赋值,否则再判断开根号之后的最大值和最小值是否相等,如果相等则区间赋值,否则区间加法。

    这题的数据也忒恶心了点吧?本来直接判断相等就能解决的问题,非要加上一个玄学的优化才能过掉...

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1e5+10,inf=0x3f3f3f3f;
     5 int n,m,a[N];
     6 ll sum[N<<2],mx[N<<2],mi[N<<2],ad[N<<2],st[N<<2];
     7 #define ls (u<<1)
     8 #define rs (u<<1|1)
     9 #define mid ((l+r)>>1)
    10 void add(int u,ll x,int l,int r) {sum[u]+=x*(r-l+1),mx[u]+=x,mi[u]+=x,ad[u]+=x;}
    11 void Set(int u,ll x,int l,int r) {sum[u]=x*(r-l+1),mx[u]=mi[u]=x,ad[u]=0,st[u]=x;}
    12 void pu(int u) {sum[u]=sum[ls]+sum[rs],mx[u]=max(mx[ls],mx[rs]),mi[u]=min(mi[ls],mi[rs]);}
    13 void pd(int u,int l,int r) {
    14     if(~st[u])Set(ls,st[u],l,mid),Set(rs,st[u],mid+1,r),st[u]=-1;
    15     if(ad[u])add(ls,ad[u],l,mid),add(rs,ad[u],mid+1,r),ad[u]=0;
    16 }
    17 void build(int u=1,int l=1,int r=n) {
    18     ad[u]=0,st[u]=-1;
    19     if(l==r) {sum[u]=mx[u]=mi[u]=a[l]; return;}
    20     build(ls,l,mid),build(rs,mid+1,r),pu(u);
    21 }
    22 void upd1(int L,int R,ll x,int u=1,int l=1,int r=n) {
    23     if(l>=L&&r<=R) {add(u,x,l,r); return;}
    24     if(l>R||r<L)return;
    25     pd(u,l,r),upd1(L,R,x,ls,l,mid),upd1(L,R,x,rs,mid+1,r),pu(u);
    26 }
    27 void upd2(int L,int R,int u=1,int l=1,int r=n) {
    28     if(l>=L&&r<=R&&mx[u]-mi[u]<=1) {
    29         if((ll)sqrt(mx[u]+0.5)==(ll)sqrt(mi[u]+0.5))Set(u,(ll)sqrt(mx[u]+0.5),l,r);
    30         else add(u,(ll)sqrt(mx[u]+0.5)-mx[u],l,r);
    31         return;
    32     }
    33     if(l>R||r<L)return;
    34     pd(u,l,r),upd2(L,R,ls,l,mid),upd2(L,R,rs,mid+1,r),pu(u);
    35 }
    36 ll qry(int L,int R,int u=1,int l=1,int r=n) {
    37     if(l>=L&&r<=R)return sum[u];
    38     if(l>R||r<L)return 0;
    39     pd(u,l,r);
    40     return qry(L,R,ls,l,mid)+qry(L,R,rs,mid+1,r);
    41 }
    42 int main() {
    43     int T;
    44     for(scanf("%d",&T); T--;) {
    45         scanf("%d%d",&n,&m);
    46         for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
    47         build();
    48         while(m--) {
    49             int f,l,r,x;
    50             scanf("%d%d%d",&f,&l,&r);
    51             if(f==1)scanf("%d",&x);
    52             if(f==1)upd1(l,r,x);
    53             else if(f==2)upd2(l,r);
    54             else if(f==3)printf("%lld
    ",qry(l,r));
    55         }
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    objective-c保护属性
    第十七章、程序管理与 SELinux 初探 工作管理 (job control)
    第十七章、程序管理与 SELinux 初探
    Shell运算符:Shell算数运算符、关系运算符、布尔运算符、字符串运算符等
    go语言初始化内部结构体3中方式
    数据结构之C语言模拟整数数组实现
    使用python将元组转换成列表,并替换其中元素
    ruby中的类实例变量和实例的实例变量
    读<<programming ruby>> 7.6节 flip-flop 理解
    ruby逻辑判断符号
  • 原文地址:https://www.cnblogs.com/asdfsag/p/11102509.html
Copyright © 2011-2022 走看看