zoukankan      html  css  js  c++  java
  • BZOJ 3110

    http://www.lydsy.com/JudgeOnline/problem.php?id=3110

    整体二分+区间修改树状数组维护

    #include<cstdio>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    inline int max(int a,int b){return a>b?a:b;}
    inline int min(int a,int b){return a<b?a:b;}
    typedef long long ll;
    const int N=50011,inf=(1<<30);
    int n,m,minn,maxx;
    int ans[N];
    ll tmp[N];
    namespace BIT{
    	ll tr1[N],tr2[N];
    	inline void add(ll *a,int p,ll v){
    		for(;p<=n;a[p]+=v,p+=p&-p);
    	}
    	inline ll query(ll *a,int p){
    		ll ret=0;
    		for(;p;ret+=a[p],p-=p&-p);
    		return ret;
    	}
    	inline void _add(int l,int r,ll v){
    		add(tr1,l,v);add(tr1,r+1,-v);
    		add(tr2,l,1ll*(l-1)*v);add(tr2,r+1,-1ll*r*v);
    	}
    	inline ll _query(ll l,ll r){
    		ll ans1=1ll*(l-1)*query(tr1,l-1)-1ll*query(tr2,l-1);
    		ll ans2=1ll*r*query(tr1,r)-1ll*query(tr2,r);
    		return ans2-ans1;
    	}
    }
    using namespace BIT;
    namespace divide{
    	struct question{
    		int a,b,c,k,pos;
    	}p[N],t[N];
    	inline void solve(int l,int r,int head,int tail){
    		if(head>tail)return;
    		if(l==r){
    			FOR(i,head,tail)
    				if(p[i].k==2)
    					ans[p[i].pos]=l;
    			return ;
    		}
    		int mid=(l+r)>>1;
    		FOR(i,head,tail){
    			if(p[i].k==1&&p[i].c>mid)_add(p[i].a,p[i].b,1ll);
    			if(p[i].k==2)tmp[i]=_query(p[i].a,p[i].b);
    		}	
    		int top=head,d;
    		FOR(i,head,tail){
    			if(p[i].k==1&&p[i].c>mid)t[top++]=p[i],_add(p[i].a,p[i].b,-1ll);
    			if(p[i].k==2)if(p[i].c<=tmp[i])t[top++]=p[i];
    		}
    		d=top;
    		FOR(i,head,tail){
    			if(p[i].k==1&&p[i].c<=mid)t[top++]=p[i];
    			if(p[i].k==2)if(p[i].c>tmp[i])p[i].c-=tmp[i],t[top++]=p[i];	
    		}
    		FOR(i,head,tail)p[i]=t[i];
    		solve(mid+1,r,head,d-1);
    		solve(l,mid,d,tail);
    	}
    }
    using namespace divide;
    int main(){
    	scanf("%d%d",&n,&m);
    	minn=inf,maxx=-inf;
    	FOR(i,1,m){
    		scanf("%d%d%d%d",&p[i].k,&p[i].a,&p[i].b,&p[i].c);
    		if(p[i].k==2)p[i].pos=++ans[0];
    		if(p[i].k==1)minn=min(minn,p[i].c),maxx=max(maxx,p[i].c);
    	}
    	solve(minn,maxx,1,m);
    	FOR(i,1,ans[0])printf("%d
    ",ans[i]);
    	return 0;
    }
    

      

    补一份树套树

    树状数组套主席树

    #include<cstdio>
    #include<algorithm>
    #define lson l,mid
    #define rson (mid+1),r
    using namespace std;
    const int maxn=1e5,N=3000000;
    int n,m,tot;
    int root[maxn],ra[maxn],rb[maxn];
    int a[maxn],b[maxn];
    struct Query{
    	char type;
    	int l,r,k;
    }q[maxn];
    struct Chainman_Tree{
    	int ls,rs,sum;
    }tr[N];
    namespace BIT_with_Chainman_Tree{
    	inline void insert(int &rt,int p,int v,int l=1,int r=b[0]){
    		tr[++tot]=tr[rt];
    		tr[rt=tot].sum+=v;
    		if(l==r)return;
    		int mid=(l+r)>>1;
    		p<=mid?insert(tr[rt].ls,p,v,lson):insert(tr[rt].rs,p,v,rson);
    	}
    	inline int ask(int k,int l=1,int r=b[0]){
    		if(l==r)return l;
    		register int sum=0;
    		for(register int i=1;i<=ra[0];++i)sum-=tr[tr[ra[i]].ls].sum;
    		for(register int i=1;i<=rb[0];++i)sum+=tr[tr[rb[i]].ls].sum;
    		int mid=(l+r)>>1;
    		if(k<=sum){
    			for(register int i=1;i<=ra[0];++i)ra[i]=tr[ra[i]].ls;
    			for(register int i=1;i<=rb[0];++i)rb[i]=tr[rb[i]].ls;
    			return ask(k,lson);
    		}
    		for(register int i=1;i<=ra[0];++i)ra[i]=tr[ra[i]].rs;			
    		for(register int i=1;i<=rb[0];++i)rb[i]=tr[rb[i]].rs;
    		return ask(k-sum,rson);
    	}
    	inline int query(int l,int r,int k){
    		ra[0]=rb[0]=0;
    		for(register int i=l-1;i;i-=i&-i)ra[++ra[0]]=root[i];
    		for(register int i=r;i;i-=i&-i)rb[++rb[0]]=root[i];
    		return ask(k);
    	}
    	inline void modify(int pos,int val,int v){
    		for(;pos<=n;pos+=pos&-pos)
    			insert(root[pos],val,v);
    	}
    }
    using namespace BIT_with_Chainman_Tree;
    inline void disc_init(){
    	sort(b+1,b+b[0]+1);
    	b[0]=unique(b+1,b+b[0]+1)-b-1;
    	for(register int i=1;i<=n;++i){
    		a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b;
    		modify(i,a[i],1);		
    	}
    }
    char s[6];
    int main(){
    	scanf("%d%d",&n,&m);
    	for(register int i=1;i<=n;++i){
    		scanf("%d",a+i);
    		b[++b[0]]=a[i];
    	}
    	for(register int i=1;i<=m;++i){
    		scanf("%s",s);
    		q[i].type=s[0];
    		if(q[i].type=='C'){
    			scanf("%d%d",&q[i].l,&q[i].k);
    			b[++b[0]]=q[i].k;
    		}
    		else
    			scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
    	}
    	disc_init();
    	for(register int i=1;i<=m;++i){
    		if(q[i].type=='C'){
    			q[i].k=lower_bound(b+1,b+b[0]+1,q[i].k)-b;
    			modify(q[i].l,a[q[i].l],-1);
    			a[q[i].l]=q[i].k;
    			modify(q[i].l,a[q[i].l],1);
    		}
    		else
    			printf("%d
    ",b[query(q[i].l,q[i].r,q[i].k)]);
    	}	
    	return 0;
    }
    

      

  • 相关阅读:
    JavaScript 金字塔
    最短路径—Dijkstra算法和Floyd算法
    Qt编程的一些技巧
    Qt-Creator 加入qwt库
    关于usr/bin/ld: cannot find -lxxx问题总结(Qt编译错误cannot find -lGL)
    根文件系统制作、NFS配置与安装及利用NFS挂载根文件系统
    tslib1.4与Qt4.8.6的交叉编译与移植
    用树莓派做3G无线路由器
    python学习笔记6:面向对象
    pyhton学习笔记5:常用模块:datatime,random,json,re
  • 原文地址:https://www.cnblogs.com/Stump/p/8012641.html
Copyright © 2011-2022 走看看