码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ5057 : 区间k小值5

时间:2017-10-09 10:01:49      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:==   min   class   scan   sum   ace   name   +=   tor   

整体二分,按时间顺序依次考虑对于权值落在$[l,r]$内的所有操作。

对于每个修改操作,若权值范围完全包含了$[l,r]$,那么在更深层的分治中它都完全包含它,对每个询问的贡献是定值,因此在当前层将贡献及时加给后面的每个询问即可。否则将该修改操作分裂成最多$2$个子操作,并往下递归分治。处理贡献均可以用树状数组实现。

对于每个询问,求出对应区间内部的和,与$k$进行比较,来决定往左还是往右递归。

时间复杂度$O(m\log^2n)$。

 

#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll;
const int N=30010;
int n,m,i,T;ll e[N][5],pre[N];vector<int>q;
inline int min(int a,int b){return a<b?a:b;}
inline int max(int a,int b){return a>b?a:b;}
struct BIT{
  ll a[N],b[N];int v[N];
  void modify(int x,ll p){for(int i=x;i<=n;i+=i&-i)if(v[i]<T)v[i]=T,a[i]=p,b[i]=p*(x-1);else a[i]+=p,b[i]+=p*(x-1);}
  ll ask(ll x){
    ll t0=0,t1=0;
    for(int i=x;i;i-=i&-i)if(v[i]==T)t0+=a[i],t1+=b[i];
    return x*t0-t1;
  }
  void add(int x,int y,ll p){modify(x,p),modify(y+1,-p);}
  ll sum(int x,int y){return ask(y)-ask(x-1);}
}bit0,bit1;
void solve(int l,int r,vector<int>q){
  if(!q.size())return;
  if(l==r){
    for(int i=0;i<q.size();i++)if(e[q[i]][0]==2)e[q[i]][4]=l;
    return;
  }
  int mid=(l+r)>>1;vector<int>ql,qr;
  T++;
  for(int i=0;i<q.size();i++){
    int x=q[i],A=e[x][1],B=e[x][2],C=e[x][3],D=e[x][4];
    if(e[x][0]==1){
      if(C<=l&&r<=D)bit0.add(A,B,1);
      else{
        int c=max(C,l),d=min(D,mid);
        if(c<=d)bit1.add(A,B,d-c+1);
        if(C<=mid)ql.push_back(x);
        if(D>mid)qr.push_back(x);
      }
    }else{
      pre[x]+=bit0.sum(A,B);
      ll tmp=pre[x]*(mid-l+1)+bit1.sum(A,B);
      if(tmp>=e[x][3])ql.push_back(x);else e[x][3]-=tmp,qr.push_back(x);
    }
  }
  solve(l,mid,ql),solve(mid+1,r,qr);
}
int main(){
  scanf("%d%d",&n,&m);
  for(i=1;i<=m;i++){
    scanf("%lld%lld%lld%lld",&e[i][0],&e[i][1],&e[i][2],&e[i][3]);
    if(e[i][0]==1)scanf("%lld",&e[i][4]);
    q.push_back(i);
  }
  solve(1,n,q);
  for(i=1;i<=m;i++)if(e[i][0]==2)printf("%lld\n",e[i][4]);
  return 0;
}

  

BZOJ5057 : 区间k小值5

标签:==   min   class   scan   sum   ace   name   +=   tor   

原文地址:http://www.cnblogs.com/clrs97/p/7639468.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!