zoukankan      html  css  js  c++  java
  • [HDU] 5306 Gorgeous Sequence [区间取min&求和&求max]

    题解:

    线段树维护区间取min求和求max

    维护最小值以及个数,次小值

    标记清除时,分情况讨论

    当lazy>max1 退出

    当max1>lazy>max2(注意不要有等号) 更新

    否则递归处理

    据吉如一的论文上说是nlogn的复杂度(至今不知论文在何处)

    卡常?? 不懂常熟技巧 那就开个o2水一下。。。。

    这数的大小 正好2^31 刚开始没看。。对拍挺对交上去wa了

    #pragma G++ optimize (2)
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 1100000
    #define INF 2147483647
    #define il inline
    struct re{
      int max1,max2,num,h,t,lazy;
      ll sum;
    }p[N*4];
    ll b[N];
    int T,n,m;
    il void updata(int x)
    {
      p[x].sum=p[x*2].sum+p[x*2+1].sum;
      p[x].max1=max(p[x*2].max1,p[x*2+1].max1);
      if (p[x*2].max1==p[x*2+1].max1)
      {
        p[x].num=p[x*2].num+p[x*2+1].num;
        p[x].max2=max(p[x*2].max2,p[x*2+1].max2);
      } else
      {
        re xx=p[x*2],yy=p[x*2+1];
        if (xx.max1<yy.max1) swap(xx,yy);
        p[x].num=xx.num;
        p[x].max2=max(xx.max2,yy.max1); 
      } 
    }
    #define mid (h+t)/2
    void build(int x,int h,int t)
    {
      p[x].h=h; p[x].t=t; p[x].lazy=INF;
      if (h==t)
      { 
        p[x].max1=b[h],p[x].max2=-INF,p[x].num=1;
        p[x].sum=b[h];
        return;
      }
      build(x*2,h,mid); build(x*2+1,mid+1,t);
      updata(x);
    }
    void down(int x)
    {
      if (p[x].max1<=p[x].lazy) p[x].lazy=INF;
      if (p[x].lazy==INF) return;
      if (p[x].h!=p[x].t)
      {
        if (p[x].lazy<p[x*2].lazy) p[x*2].lazy=p[x].lazy;
        if (p[x].lazy<p[x*2+1].lazy) p[x*2+1].lazy=p[x].lazy;    
      } 
      if (p[x].max1>p[x].lazy&&p[x].max2<p[x].lazy)
      {
        p[x].sum=p[x].sum-1ll*(p[x].max1-p[x].lazy)*p[x].num;
        p[x].max1=p[x].lazy;
      } else
      {
        down(x*2); down(x*2+1);
        updata(x);
      }
      p[x].lazy=INF;
    }
    void change(int x,int h,int t,int w)
    {
      down(x);
      if (p[x].h>t||p[x].t<h) return;
      if (h<=p[x].h&&p[x].t<=t)
      {
        p[x].lazy=min(p[x].lazy,w); down(x); return;
      }
      change(x*2,h,t,w); change(x*2+1,h,t,w);
      updata(x);
    }
    int query1(int x,int h,int t)
    {
      down(x);
      if (p[x].h>t||p[x].t<h) return(-INF);
      if (h<=p[x].h&&p[x].t<=t) return(p[x].max1);
      return(max(query1(x*2,h,t),query1(x*2+1,h,t)));
    }
    ll query2(int x,int h,int t)
    {
      down(x);
      if (p[x].h>t||p[x].t<h) return(0);
      if (h<=p[x].h&&p[x].t<=t) return(p[x].sum);
      return(query2(x*2,h,t)+query2(x*2+1,h,t));
    }
    int main()
    {
      freopen("noip.in","r",stdin);
      freopen("noip.out","w",stdout);
      std::ios::sync_with_stdio(false);
      cin>>T;
      for (int ttt=1;ttt<=T;ttt++)
      {
       // clear();
        cin>>n>>m;
        for (int i=1;i<=n;i++) cin>>b[i];
        build(1,1,n);
        for (int i=1;i<=m;i++)
        {
          int x,y,z,w;
          cin>>x;
          if (x==0)
          {
            cin>>y>>z>>w;
            change(1,y,z,w);
          }
          if (x==1)
          {
            cin>>y>>z;
            cout<<query1(1,y,z)<<endl;
          }
          if (x==2)
          {
            cin>>y>>z;
            cout<<query2(1,y,z)<<endl;
          }
        }
      }
      return 0;
    }
  • 相关阅读:
    JS设计模式(11)中介者模式
    PHP实现微信模板消息发送给指定用户
    PHP浮点精度问题
    PHP微信红包生成算法的程序源码(用抛物线的模型实现)
    PHP队列的实现详细操作步骤
    PHP数组函数实现栈与队列的方法介绍(代码示例)
    Laravel 事务中使用悲观锁
    array_reduce — 用回调函数迭代地将数组简化为单一的值
    PHP上传文件和下载
    php导出xls,报错:文件格式和扩展名不匹配。该文件可能已损坏或不安全。除非你相信它的来源,否则不要打开它。
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8784366.html
Copyright © 2011-2022 走看看