zoukankan      html  css  js  c++  java
  • BZOJ4552 [Tjoi2016&Heoi2016]排序 【二分 + 线段树】

    题目链接

    BZOJ4552

    题解

    之前去雅礼培训做过一道题,(O(nlogn))维护区间排序并能在线查询
    可惜我至今不能get

    但这道题有着(O(nlog^2n))的离线算法
    我们看到询问只有一个,自然可以去尝试二分
    我们二分一个值,就只关心最终那个位置的值和其的大小关系
    所以我们可以令所有(ge)它的值为(1),剩余为(0)
    然后我们只需对只有(0)(1)的序列排序,用一个线段树很轻松就能解决

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    #define ls (u << 1)
    #define rs (u << 1 | 1)
    using namespace std;
    const int maxn = 100005,maxm = 100005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    int n,m,opt[maxn],ql[maxn],qr[maxn],a[maxn],M,q;
    int sum[maxn << 2],tag[maxn << 2];
    void upd(int u){sum[u] = sum[ls] + sum[rs];}
    void pd(int u,int l,int r){
    	if (tag[u] == 1){
    		int mid = l + r >> 1;
    		sum[ls] = mid - l + 1;
    		sum[rs] = r - mid;
    		tag[ls] = tag[rs] = 1;
    		tag[u] = 0;
    	}
    	else if (tag[u] == 2){
    		sum[ls] = sum[rs] = 0;
    		tag[ls] = tag[rs] = 2;
    		tag[u] = 0;
    	}
    }
    void build(int u,int l,int r){
    	tag[u] = 0;
    	if (l == r){
    		sum[u] = (a[l] >= M);
    		return;
    	}
    	int mid = l + r >> 1;
    	build(ls,l,mid);
    	build(rs,mid + 1,r);
    	upd(u);
    }
    void modify(int u,int l,int r,int L,int R,int v){
    	if (l >= L && r <= R){sum[u] = v * (r - l + 1); tag[u] = v ? 1 : 2; return;}
    	pd(u,l,r);
    	int mid = l + r >> 1;
    	if (mid >= L) modify(ls,l,mid,L,R,v);
    	if (mid < R) modify(rs,mid + 1,r,L,R,v);
    	upd(u);
    }
    int query(int u,int l,int r,int L,int R){
    	if (l >= L && r <= R) return sum[u];
    	pd(u,l,r);
    	int mid = l + r >> 1;
    	if (mid >= R) return query(ls,l,mid,L,R);
    	if (mid < L) return query(rs,mid + 1,r,L,R);
    	return query(ls,l,mid,L,R) + query(rs,mid + 1,r,L,R);
    }
    bool check(int x){
    	M = x; int l,r,s;
    	build(1,1,n);
    	REP(i,m){
    		l = ql[i]; r = qr[i];
    		s = query(1,1,n,l,r);
    		if (!opt[i]){
    			if (s) modify(1,1,n,r - s + 1,r,1);
    			if (s != r - l + 1) modify(1,1,n,l,r - s,0);
    		}
    		else {
    			if (s) modify(1,1,n,l,l + s - 1,1);
    			if (s != r - l + 1) modify(1,1,n,l + s,r,0);
    		}
    	}
    	return query(1,1,n,q,q) == 1;
    }
    int main(){
    	n = read(); m = read();
    	REP(i,n) a[i] = read();
    	REP(i,m) opt[i] = read(),ql[i] = read(),qr[i] = read();
    	q = read();
    	int l = 1,r = n,mid;
    	while (l < r){
    		mid = (l + r + 1) >> 1;
    		if (check(mid)) l = mid;
    		else r = mid - 1;
    	}
    	printf("%d
    ",l);
    	return 0;
    }
    
    
  • 相关阅读:
    模块入门–搜索
    [hadoop源码阅读][2]package结构
    [hadoop源码阅读][8]datanodeDataStorage
    [hadoop源码阅读][4]org.apache.hadoop.io
    [hadoop源码阅读][6]org.apache.hadoop.ipcprotocol和心跳分析
    [hadoop源码阅读][1]源码目录结构
    [hadoop源码阅读][4]org.apache.hadoop.io.compress系列3使用压缩
    [hadoop源码阅读][3]新旧api区别
    [hadoop源码阅读][6]org.apache.hadoop.ipcipc总体结构和RPC
    [hadoop源码阅读][8]datanodeFSDataset
  • 原文地址:https://www.cnblogs.com/Mychael/p/9041832.html
Copyright © 2011-2022 走看看