zoukankan      html  css  js  c++  java
  • 【BZOJ4979】凌晨三点的宿舍(分治)

    传送门

    给定一个序列,每个位置一个值hih_i
    定义22个位置(i,j),i<j(i,j),i<j的距离为ji+hi+hj2min(h[k],k[i,j])j-i+h_i+h_j-2*min(h[k],kin[i,j])
    求有多少对节点的距离小于等于kk
    n2e5n le2e5


    考虑分治
    对于当前区间l,mid,rl,mid,r
    mnimn_i表示iimidmid的最小值
    求有多少i[l,mid],j[mid+1,r]iin[l,mid],jin[mid+1,r]满足
    ji+hi+hj2min(mni,mnj)kj-i+h_i+h_j-2*min(mn_i,mn_j)le k
    假设此时min=mnimin=mn_i,另一种会在相反的i,ji,j统计到
    hii2mnikjhjh_i-i-2*mn_ile k-j-h_j
    对每个ii插入树状数组后对jj查询就是了
    复杂度O(nlog2n)O(nlog^2n)

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pii pair<int,int>
    #define mk make_pair
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=200005;
    const int Mr=600006;
    const int M=1000005;
    #define lowbit(x) (x&(-x))
    struct Bit{
    	int tr[M];
    	inline void update(int p,int k){
    		p+=Mr;
    		for(;p<M;p+=lowbit(p))tr[p]+=k;
    	}
    	inline int query(int p,int res=0){
    		p=min(p+Mr,M-1);
    		for(;p;p-=lowbit(p))res+=tr[p];
    		return res;
    	}
    }A,B;
    int n,m,k,h[N];
    ll ans;
    vector<pii> q;
    struct room{
    	int x,y,val;
    	room(int _x=0,int _y=0,int _val=0):x(_x),y(_y),val(_val){}
    	friend inline bool operator <(const room &a,const room &b){
    		return a.val<b.val;
    	}
    };
    inline void calc(const vector<pii> &q){
    	for(int i=0,j=0;i<q.size();i++){
    		while(q[j].second+k<q[i].second)j++;
    		ans+=i-j;
    	}
    }
    inline void solve(int l,int r,vector<pii> &vec){
    	if(!vec.size())return;
    	if(l==r)return calc(vec);
    	int mid=((l+r)>>1);
    	vector<pii> ql,qr;
    	for(int i=0;i<vec.size();i++){
    		if(vec[i].first<=mid)ql.push_back(vec[i]);
    		else qr.push_back(vec[i]);
    	}
    	solve(l,mid,ql),solve(mid+1,r,qr);
    	vector<room> now;
    	for(int i=ql.size()-1,p=mid,mn=h[p];~i;p--){
    		mn=min(mn,h[p]);
    		while(~i&&ql[i].first==p){
    			now.push_back(room(p,ql[i].second,min(mn,ql[i].second)));
    			i--;
    		}
    	}
    	for(int i=0,p=mid+1,mn=h[p];i<qr.size();p++){
    		mn=min(mn,h[p]);
    		while(i<qr.size()&&qr[i].first==p){
    			now.push_back(room(p,qr[i].second,min(mn,qr[i].second)));
    			i++;
    		}
    	}
    	sort(now.begin(),now.end());
    	for(int i=0;i<now.size();i++){
    		room &t=now[i];
    		if(t.x<=mid){
    			A.update(t.y-t.x-2*t.val,1);
    			ans+=B.query(k+t.x-t.y);
    		}
    		else{
    			B.update(t.y+t.x-2*t.val,1);
    			ans+=A.query(k-t.x-t.y);
    		}
    	}
    	for(int i=0;i<now.size();i++){
    		room &t=now[i];
    		if(t.x<=mid)A.update(t.y-t.x-2*t.val,-1);
    		else B.update(t.y+t.x-2*t.val,-1);
    	}
    }
    int main(){
    	n=read(),k=read();
    	for(int i=1;i<=n;i++)h[i]=read();
    	m=read();
    	for(int i=1;i<=m;i++){
    		int x=read(),y=read();
    		q.push_back(mk(x,y));
    	}
    	sort(q.begin(),q.end());
    	solve(1,n,q);
    	cout<<ans;
    }
    
  • 相关阅读:
    润乾报表之图片导出不显示
    润乾报表之前言
    ActionSheet & alertView
    OC基础知识
    状态栏的设置
    计算机的存储单位
    autoreleass的基本使用
    图片选择器(UIImagePickerController)
    Foundation
    Block
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145642.html
Copyright © 2011-2022 走看看