求助O(nlogn)
查看原帖
求助O(nlogn)
253342
HYX1124楼主2022/3/28 18:34

一个权值线段树 + 一个平衡树

为啥过不了啊

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;

typedef long long ll;
inline int read()
{
	int now=0,nev=1; char c=getchar();
	while(c<'0' || c>'9') { if(c=='-') nev=-1; c=getchar();}
	while(c>='0' && c<='9') { now=(now<<1)+(now<<3)+(c&15); c=getchar(); }
	return now*nev;
}

const int N = 1e6 + 10;
int a[N], b[N], n, m;
int sta[N], stb[N], top = 1, pos[N], pre[N];

namespace Val_SEG{

	struct Node{
		int l, r, v;
	} node[N << 1];

	void pushup(int id){
		node[id].v = max(node[id << 1].v, node[id << 1 | 1].v);
	}

	void build(int id, int l, int r){
		node[id].l = l, node[id].r = r;
		node[id].v = 0;
		if(l == r) return;
		int mid = (l + r) >> 1;
		build(id << 1, l, mid), build(id << 1 | 1, mid + 1, r);
	}

	void upd(int id, int x, int v){
		if(node[id].l == node[id].r) return void(node[id].v = v);
		if(x <= node[id << 1].r) upd(id << 1, x, v);
		else upd(id << 1 | 1, x, v);
		pushup(id);
	}

	int query(int id, int l, int r){
		if(node[id].r < l || node[id].l > r) return 0;
		if(l <= node[id].l && node[id].r <= r) return node[id].v;
		return max(query(id << 1, l, r), query(id << 1 | 1, l, r));
	}

} // end Val_SEG

namespace FHQ_Treap{

	const int INF = 2147483647;

	struct node{
		int lson, rson, size, key, val;
	} p[N << 1];

	int tot = 1, ROOT;

	void pushup(int root){
		if(!root) return;
		p[root].size = p[p[root].lson].size + p[p[root].rson].size + 1;
	}

	int make(int val){
		int root = ++tot;
		p[root].val = val;
		p[root].size = 1;
		p[root].lson = p[root].rson = 0;
		p[root].key = rand();
		return root;
	}

	void split(int root, int val, int &x, int &y){
		if(!root) return void(x = y = 0);
		if(val >= p[root].val) {
			x = root;
			split(p[root].rson, val, p[root].rson, y);
		} else {
			y = root;
			split(p[root].lson, val, x, p[root].lson);
		}
		pushup(root);
	}

	int merge(int x, int y){
		if(!x || !y) return x + y;
		if(p[x].key > p[y].key) {
			p[x].rson = merge(p[x].rson, y);
			pushup(x);
			return x;
		} else {
			p[y].lson = merge(x, p[y].lson);
			pushup(y);
			return y;
		}
	}

	void insert(int val){
		int x, y;
		split(ROOT, val - 1, x, y);
		ROOT = merge(merge(x, make(val)), y);
	}

	int rank(int val){
		int x, y, res;
		split(ROOT, val - 1, x, y);
		res = p[x].size;
		ROOT = merge(x, y);
		return res;
	}

	void build(){
		ROOT = make(INF);
	}

} // end FHQ_Treap

typedef pair<int, int> pii;
vector<int> que[N];
map<pii, int> ans;
int l[N], r[N];

int main()
{
    //freopen("stack.in", "r", stdin);
    //freopen("stack.out", "w", stdout);

    n = read(), m = read();
    for(int i = 1; i <= n; ++i) a[i] = read();
    for(int i = 1; i <= n; ++i) b[i] = read();
    for(int i = 1; i <= n; ++i){
        while(top && (a[i] == sta[top] || b[i] >= stb[top])) --top;
        pos[i] = ++top;
        sta[top] = a[i], stb[top] = b[i];
    }

    Val_SEG::build(1, 1, n);
    for(int i = 1; i <= n; ++i){
        Val_SEG::upd(1, pos[i], i);
        pre[i] = Val_SEG::query(1, 1, pos[i] - 1);
    }

	for(int i = 1; i <= m; ++i){
		l[i] = read(), r[i] = read();
		que[l[i] - 1].push_back(l[i]);
		que[r[i]].push_back(l[i]);
	}
	FHQ_Treap::build();
    for(int i = 1; i <= n; ++i){
		FHQ_Treap::insert(pre[i]);
		for(int j : que[i])
			ans[pii(i, j)] = FHQ_Treap::rank(j);
	}
	for(int i = 1; i <= m; ++i){
		printf("%d\n",  ans[pii(r[i], l[i])] - ans[pii(l[i] - 1, l[i])]);
	}

    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
2022/3/28 18:34
加载中...