BZOJ 1112: [POI2008]砖块Klo 线段树维护区间中位数
2016-11-04 16:09
435 查看
时空隧道
翻译一下就是求出任意长度为k的区间的中位数
代码如下:
翻译一下就是求出任意长度为k的区间的中位数
代码如下:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> //by NeighThorn #define inf 100000000000 using namespace std; const int maxn=100000+5,maxh=1000000+5; int n,k,h[maxn],m,midnum; long long ans; struct Tree{ int l,r,cnt; long long sum; }tree[maxh*4]; struct M{ int cnt; long long sum; M(long long x=0,int y=0){ sum=x,cnt=y; } }aql,anqila; inline int read(void){ char ch=getchar();int x=0; while(!(ch>='0'&&ch<='9')) ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x; } inline void build(int l,int r,int tr){ tree.l=l,tree .r=r,tree .sum=tree .cnt=0; if(l==r) return; int mid=(l+r)>>1; build(l,mid,tr<<1);build(mid+1,r,tr<<1|1); } inline void change(int pos,int val,int tr){ if(tree .l==tree .r){ tree .cnt+=val;tree .sum+=val*pos; return; } int mid=(tree .l+tree .r)>>1; if(pos<=mid) change(pos,val,tr<<1); else change(pos,val,tr<<1|1); tree .cnt=tree[tr<<1].cnt+tree[tr<<1|1].cnt; tree .sum=tree[tr<<1].sum+tree[tr<<1|1].sum; } inline int querynum(int num,int tr){ if(tree .l==tree .r) return tree .l; if(tree[tr<<1].cnt<num) return querynum(num-tree[tr<<1].cnt,tr<<1|1); else return querynum(num,tr<<1); } inline M querysum(int l,int r,int tr){ if(l<-1) return M(0,0); if(l>r) return M(0,0); if(tree .l==l&&tree .r==r) return M(tree .sum,tree .cnt); int mid=(tree .l+tree .r)>>1; if(r<=mid) return querysum(l,r,tr<<1); else if(l>mid) return querysum(l,r,tr<<1|1); else{ M tmp=querysum(l,mid,tr<<1),temp=querysum(mid+1,r,tr<<1|1); tmp.cnt+=temp.cnt,tmp.sum+=temp.sum; return tmp; } } signed main(void){ n=read();k=read();m=0; for(int i=1;i<=n;i++) h[i]=read(),m=max(m,h[i]); if(k==1){ puts("0");return 0; } build(0,m,1);midnum=(1+k)>>1; for(int i=1;i<=k;i++) change(h[i],1,1); int lala=querynum(midnum,1);aql=querysum(0,lala-1,1),anqila=querysum(lala+1,m,1);ans=aql.cnt*lala-aql.sum+anqila.sum-lala*anqila.cnt; // cout<<"lala"<<lala<<" "<<ans<<endl; for(int i=k+1;i<=n;i++) change(h[i-k],-1,1),change(h[i],1,1),lala=querynum(midnum,1),/*cout<<"lala"<<lala<<" ",*/aql=querysum(0,lala-1,1),anqila=querysum(lala+1,m,1)/*,cout<<aql.cnt<<" "<<aql.sum<<" "<<anqila.cnt<<" "<<anqila.sum<<endl*/,ans=min(ans,aql.cnt*lala-aql.sum+anqila.sum-lala*anqila.cnt)/*,cout<<ans<<endl*/; printf("%lld\n",ans); return 0; }
by >_< NeighThorn相关文章推荐
- [BZOJ 1112] [POI2008] 砖块Klo 【区间K大】
- BZOJ 1112 [POI2008]砖块Klo(可持久化线段树)
- bzoj1112 [POI2008]砖块Klo
- BZOJ1112 - [POI2008]砖块Klo
- bzoj1112 [POI2008]砖块Klo(平衡树/map/树状数组)
- BZOJ 1112: [POI2008]砖块Klo
- BZOJ 1112 POI2008 砖块Klo Treap
- BZOJ1112 - [POI2008]砖块Klo
- BZOJ1112: [POI2008]砖块Klo
- bzoj 1112: [POI2008]砖块Klo(splay)
- BZOJ 1112 [POI2008]砖块Klo Treap
- bzoj1112 POI2008 砖块Klo 树状数组
- 【BZOJ 1112】 [POI2008]砖块Klo
- bzoj 1112: [POI2008]砖块Klo treap
- 【bzoj1112】[POI2008]砖块Klo
- 两道Splay小结--bzoj1112: [POI2008]砖块Klo&bzoj1588: [HNOI2002]营业额统计
- bzoj1112: [POI2008]砖块Klo
- Bzoj1112:[POI2008]砖块Klo:splay
- 【bzoj 1112】砖块Klo(权值线段树)
- [BZOJ1112][POI2008]砖块Klo(splay)