• bzoj3343: 教主的魔法 分块 标记


    修改:两边暴力重构,中间打标记。复杂度:O(n0.5)

    查询:中间二分两边暴力。O(n0.5logn0.5)

    总时间复杂度O(n*n0.5logn0.5)

    空间复杂度是n级别的

    标记不用下传因为标记不用下传也没时间下传,如果在访问时下传就造成更棘手的不整块,如果累加式下传不好记录,所以就带着就行。

    细节很多......

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define MAXN 1010000
    using namespace std;
    typedef long long LL;
    LL a[MAXN],b[1010][1010],mark[1010],n,pos[MAXN],lon,t;
    inline LL Min(LL x,LL y)
    {
       return x<y?x:y;
    }
    int comp(const int x,const int y)
    {
       return x>y;
    }
    inline void work1()
    {
       LL l,r,w;
       scanf("%lld%lld%lld",&l,&r,&w);
       LL z=pos[l]+1,y=pos[r]-1;
       for(LL i=z;i<=y;i++)
        mark[i]+=w;
       LL zzh=(pos[l]*lon);
       zzh=Min(zzh,r);
       for(LL i=l;i<=zzh;i++) a[i]+=w;
       zzh=pos[l]*lon;
       zzh=Min(zzh,n);
       memset(b[pos[r]],0,sizeof(b[pos[r]]));
       for(LL i=zzh-lon+1;i<=zzh;i++) b[pos[l]][i%lon+1]=a[i];
       sort(b[pos[l]]+1,b[pos[l]]+lon+1);
       if(pos[l]!=pos[r])
       {
           for(LL i=(pos[r]-1)*lon+1;i<=r;i++) a[i]+=w;
           zzh=pos[r]*lon;
           zzh=Min(zzh,n);
           memset(b[pos[r]],0,sizeof(b[pos[r]]));
           for(LL i=(pos[r]-1)*lon+1;i<=zzh;i++) b[pos[r]][i%lon+1]=a[i];
           sort(b[pos[r]]+1,b[pos[r]]+lon+1);
       }
    }
    inline LL Count(LL p,LL c)
    {
       LL ans=0,l=1,r=lon;
       while(l<=r)
       {
         LL mid=(l+r)>>1;
         if(b[p][mid]+mark[p]<c)
          l=mid+1;
         else
          ans+=(r-mid+1),r=mid-1;
       }
       return ans;
    }
    inline void work2()
    {
       LL l,r,c,ans=0;
       scanf("%lld%lld%lld",&l,&r,&c);
       LL z=pos[l]+1,y=pos[r]-1;
       for(LL i=z;i<=y;i++)
          ans+=Count(i,c);
       LL zzh=(pos[l]*lon);
       zzh=Min(zzh,r);
       for(LL i=l;i<=zzh;i++)
         if(a[i]+mark[pos[i]]>=c)
           ans++;
       if(pos[l]!=pos[r])
       {
          for(LL i=(pos[r]-1)*lon+1;i<=r;i++)
           if(a[i]+mark[pos[i]]>=c)
             ans++;
       }
       printf("%lld
    ",ans);
    }
    int main()
    {
       scanf("%lld",&n);
       LL Q;
       scanf("%lld",&Q);
       lon=(LL)sqrt(n+0.5);
       for(LL i=1;i<=n;i++)
       {
          scanf("%lld",&a[i]);
          pos[i]=(i-1)/lon+1;
          b[pos[i]][i%lon+1]=a[i];
       }
       t=pos[n];
       for(int i=1;i<=t;i++)
        sort(b[i]+1,b[i]+lon+1);
       while(Q--)
       {
         char s[2];
         scanf("%s",s);
         if(s[0]=='M')work1();
         else work2();
       }
       return 0;
    }
    苟利国家生死以, 岂因祸福避趋之。
  • 相关阅读:
    uva299 Train Swapping
    uva 10106 Product
    uva 340 MasterMind Hints
    uva 10115 Automatic Editing
    uva748 Exponentiation
    uva152 Tree's a Crowd
    uva 10420 List of Conquests
    uva 644 Immediate Decodability
    要知其所以然的学习(转载)
    持有书籍统计
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7007731.html
Copyright © 2020-2023  润新知