zoukankan      html  css  js  c++  java
  • 题解

    [HEOI2016/TJOI2016]排序

    题目描述

    给出一个 1 到 n 的排列,现在对这个排列序列进行 m 次局部排序,排序分为两种:

    • 0 l r 表示将区间 ([l,r]) 的数字升序排序
    • 1 l r 表示将区间 ([l,r]) 的数字降序排序

    注意,这里是对下标在区间 ([l,r]) 内的数排序。
    最后询问第 q 位置上的数字。
    解题思路

    注意询问只有一个,我们可以很难想到用二分答案,假设答案是mid,然后把所有大于等于mid的数

    当做1,小于mid的数当做0,这样我们可以吧排序问题转化成了区间变成问题,我们就可以用线段树

    来维护了,我们可以统计出线段树每个区间中1的个数,查询要排序的区间中1的个数记为cnt,如果

    按降序排,前cnt个数变1,剩下的变为0,最后查找要询问的数,如果是1,二分答案向左半边找,反

    之向右半边找。

    #include<iostream>
    #include<cstdio>
    #define l(o) (o<<1)
    #define r(o) (o<<1|1)
    #define mid ((l+r)>>1)
    using namespace std;
    const int N=2e5+7;
    int n,m,p;
    int a[N];
    
    struct node{
    	int opt,l,r;
    }q[N];
    
    int sum[N<<2],tag[N<<2];
    
    void modify(int o,int l,int r,int val){
    	tag[o]=val;
    	sum[o]=(r-l+1)*val;
    }
    
    void up(int o){
    	sum[o]=sum[l(o)]+sum[r(o)];
    }
    
    void down(int o,int l,int r){
    	if(tag[o]!=-1){
    		modify(l(o),l,mid,tag[o]);
    		modify(r(o),mid+1,r,tag[o]);
    		tag[o]=-1;
    	}
    }
    
    void build(int o,int l,int r,int x){
    	tag[o]=-1;
    	if(l==r){
    		sum[o]=(a[l]>=x);
    		return;
    	}
    	build(l(o),l,mid,x);
    	build(r(o),mid+1,r,x);
    	up(o);
    }
    
    void change(int o,int l,int r,int L,int R,int val){
    	if(L<=l&&R>=r){
    		modify(o,l,r,val);
    		return;
    	}
    	down(o,l,r);
    	if(L<=mid)change(l(o),l,mid,L,R,val);
    	if(R>mid)change(r(o),mid+1,r,L,R,val);
    	up(o);
    }
    
    int ask(int o,int l,int r,int L,int R){
    	if(L<=l&&R>=r){
    		return sum[o];
    	}
    	down(o,l,r);
    	int res=0;
    	if(L<=mid)res+=ask(l(o),l,mid,L,R);
    	if(R>mid)res+=ask(r(o),mid+1,r,L,R);
    	return res;
    }
    
    int judge(int x){
    	 build(1,1,n,x);
    	 int cnt;
    	 for(int i=1;i<=m;i++){
    	 	cnt=ask(1,1,n,q[i].l,q[i].r);
    	 	if(q[i].opt==1){
    	 		if(cnt!=0)change(1,1,n,q[i].l,q[i].l+cnt-1,1);
    	 		change(1,1,n,q[i].l+cnt,q[i].r,0);
    			  
    	 	}else{
    	 		change(1,1,n,q[i].l,q[i].r-cnt,0);
    	 		if(cnt!=0)change(1,1,n,q[i].r-cnt+1,q[i].r,1);
    			 
    	 	}
    	 }
    	 return ask(1,1,n,p,p);
    //	 return 0;
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&q[i].opt,&q[i].l,&q[i].r);
    	} 
    	scanf("%d",&p);
    	int l1=1,r1=n;
    	int ans;
    	while(l1<=r1){
    		int mid1=(l1+r1)>>1;
    		if(judge(mid1)){
    			ans=mid1;
    			l1=mid1+1;
    		}else r1=mid1-1;
    	}
    	cout<<ans;
    }
    
  • 相关阅读:
    leetcode33. Search in Rotated Sorted Array
    pycharm 设置sublime text3 monokai主题
    django class Meta
    leetcode30, Substring With Concatenation Of All Words
    Sublime text3修改tab键为缩进为四个空格,
    sublime text3 python打开图像的问题
    安装上imesupport输入法依然不跟随的解决办法,
    sublime text3 的插件冲突弃用问题,
    sublime text3 BracketHighlighter括号匹配的设置
    windows 下wget的使用
  • 原文地址:https://www.cnblogs.com/Aswert/p/13369022.html
Copyright © 2011-2022 走看看