zoukankan      html  css  js  c++  java
  • [洛谷P2617]Dynamic Rankings

    题目大意:给你$n$个数,有两个操作:

    1. $Q;l;r;k:$求出区间$[l,r]$中第$k$大
    2. $C;i;t:$把第$i$个数改成$t$

    题解:多人尝试得,现在这道题线段树套线段树过不去,所以我学习了一下树状数组套线段树,线段树只维护值域上的区间和,把树状数组询问部分变成这么多棵线段树相减,这样就可以在线段树上二分了

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cctype>
    namespace __IO {
    	namespace R {
    		int x, ch;
    		inline int read() {
    			ch = getchar();
    			while (isspace(ch)) ch = getchar();
    			for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
    			return x;
    		}
    		inline char readc() {
    			ch = getchar();
    			while (!isalpha(ch)) ch = getchar();
    			return static_cast<char> (ch);
    		}
    	}
    }
    using __IO::R::read;
    using __IO::R::readc;
    
    #define maxn 100010
    #define N (maxn * 400)
    const int maxl = 0, maxr = 1e9;
    
    int n, m;
    int s[maxn], v[maxn << 1];
    namespace SgT {
    	int V[N], lc[N], rc[N], idx;
    	int num, op;
    	void modify(int &rt, int l, int r) {
    		if (!rt) rt = ++idx;
    		V[rt] += op;
    		if (l == r) return ;
    		int mid = l + r >> 1;
    		if (num <= mid) modify(lc[rt], l, mid);
    		else modify(rc[rt], mid + 1, r);
    	}
    	int rtL[maxn], rtR[maxn];
    	int totL, totR;
    	int query(int l, int r, int k) {
    		if (l == r) return l;
    		int tmp = 0, mid = l + r >> 1;
    		for (int i = 1; i <= totL; i++) tmp -= V[lc[rtL[i]]];
    		for (int i = 1; i <= totR; i++) tmp += V[lc[rtR[i]]];
    		if (tmp >= k) {
    			for (int i = 1; i <= totL; i++) rtL[i] = lc[rtL[i]];
    			for (int i = 1; i <= totR; i++) rtR[i] = lc[rtR[i]];
    			return query(l, mid, k);
    		} else {
    			for (int i = 1; i <= totL; i++) rtL[i] = rc[rtL[i]];
    			for (int i = 1; i <= totR; i++) rtR[i] = rc[rtR[i]];
    			return query(mid + 1, r, k - tmp);
    		}
    	}
    }
    namespace BIT {
    	int rt[maxn];
    	void modify(int p, int num, int op = 1) {
    		SgT::num = num, SgT::op = op;
    		for (; p <= n; p += p & -p) SgT::modify(rt[p], maxl, maxr);
    	}
    	int query(int l, int r, int k) {
    		l--;
    		SgT::totL = 0, SgT::totR = 0;
    		for (int i = l; i; i &= i - 1) SgT::rtL[++SgT::totL] = rt[i];
    		for (int i = r; i; i &= i - 1) SgT::rtR[++SgT::totR] = rt[i];
    		return SgT::query(maxl, maxr, k);
    	}
    }
    
    int main() {
    	n = read(), m = read();
    	for (int i = 1; i <= n; i++) {
    		s[i] = read();
    		BIT::modify(i, s[i]);
    	}
    	while (m --> 0) {
    		char op = readc();
    		int l = read(), r = read(), k;
    		if (op == 'Q') {
    			k = read();
    			printf("%d
    ", BIT::query(l, r, k));
    		} else {
    			BIT::modify(l, s[l], -1);
    			s[l] = r;
    			BIT::modify(l, s[l]);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    娓娓道来c指针 (4)解析c的声明语句
    Snail—UI学习之UITextField
    E
    Qt录音机
    著名的英文搜索引擎
    java中Map,List与Set的差别
    Android图片处理:识别图像方向并显示
    Unity3D中组件事件函数的运行顺序
    Android屏幕density, dip等相关概念总结
    Codeforces Round #257 (Div. 2)
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10038374.html
Copyright © 2011-2022 走看看