zoukankan      html  css  js  c++  java
  • AHOI2013 作业

    第一问就是主席树了。

    依据套路, 对于每个数 x, 记录上一次出现的位置 prex, 于是问题就变成了: 查询区间 [l,r] 内, 值域 [a,b] 内, pre [0,l-1] 内的数, 是个三维的偏序问题。

    看上去一般做法要 O(log3), 但没有修改, 可以可持久化降一维。

    然后剩下的二维问题就树套树解决了。

    当然,开玩笑的, 第一维离线降下来就行了。

    #include<bits/stdc++.h>
    #define INF 2147483647
    using namespace std;
    
    const int N = 1e5 + 3, SZ = N*20*2+233;
    
    int n, m, a[N], las[N], pre[N];
    
    struct ques {
    	int l, r, a, b;
    	int ans1, ans2;
    } obj[N];
    
    int ecnt, hd[N], nt[N*2+3], vr[N*2+3];
    void ad(int u, int v) { nt[++ecnt] = hd[u], hd[u] = ecnt; vr[ecnt] = v; }
    
    namespace BIT {
    	int t[N];
    	void ins(int x) {
    		for(; x<=n; x+=(x&(-x))) ++t[x];
    	}
    	int ask_(int x) {
    		int res = 0;
    		for(; x; x-=x&(-x)) res += t[x];
    		return res;
    	}
    	int ask(int l, int r) { return ask_(r) - ask_(l-1); }
    }
    
    int cnt;
    #define newnode(s, v, a, b) (&(*pool[cnt++] = node(s, v, a, b)))
    #define merge(a, b) newnode(a->siz+b->siz, b->val, a, b)
    #define upd(me) if(me->ls->siz) me->siz=me->ls->siz+me->rs->siz, me->val=me->rs->val
    struct node {
    	int siz, val;
    	node *ls, *rs;
    	node(int s, int v, node *a, node *b) : siz(s), val(v), ls(a), rs(b) {
    	}
    	node() {
    	}
    } *root[N], *emp, t[SZ], *pool[SZ];
    
    inline void maintain(node *me) {
    	if(me->ls->siz > me->rs->siz * 4)
    		me->rs = merge(me->ls->rs, me->rs), pool[--cnt] = me->ls, me->ls = me->ls->ls;
    	if(me->rs->siz > me->ls->siz * 4)
    		me->ls = merge(me->ls, me->rs->ls), pool[--cnt] = me->rs, me->rs = me->rs->rs;
    }
    
    void ins(int x, node *me) {
    	if(me->siz == 1)
    		me->ls = newnode(1, min(x, me->val), emp, emp),
    		me->rs = newnode(1, max(x, me->val), emp, emp);
    	else
    		ins(x, x>me->ls->val ? me->rs : me->ls), maintain(me);
    	upd(me);
    }
    
    int low(int x, node *me) {
    	if(me->siz == 1) return (me->val <= x);
    	else return x>=me->ls->val ? me->ls->siz + low(x, me->rs) : low(x, me->ls);
    }
    
    namespace nbBIT {
    	void ins(int x, int v) {
    		for(; x<=n; x+=(x&(-x))) ins(v, root[x]);
    	}
    	int ask_(int x, int v) {
    		int res = 0;
    		for(; x; x-=(x&(-x))) res += low(v, root[x]);
    		return res;
    	}
    	int ask(int l, int r, int v) {
    		return ask_(r, v) - ask_(l-1, v);
    	}
    } 
    
    int main() {
    	emp = new node(0, 0, NULL, NULL);
    	for(int i=0; i<SZ; ++i) pool[i] = &t[i];
    	scanf("%d%d", &n, &m);
    	for(int i=1; i<=n; ++i) root[i] = newnode(1, INF, emp, emp);
    	
    	for(int i=1; i<=n; ++i) {
    		scanf("%d", &a[i]);
    		pre[i] = las[a[i]];
    		las[a[i]] = i;
    	}
    	// May I have your Name ?
    	for(int i=1; i<=m; ++i) {
    		scanf("%d%d%d%d", &obj[i].l, &obj[i].r, &obj[i].a, &obj[i].b);
    		obj[i].ans1 = obj[i].ans2 = 0;
    		if(obj[i].l - 1) ad(obj[i].l - 1, i);
    		ad(obj[i].r, i);
    	}
    	// My name is F#
    	
    	for(int i=1; i<=n; ++i) {
    		BIT::ins(a[i]);
    		nbBIT::ins(a[i], pre[i]);
    //		cout << "# " << pre[i] << '
    ';
    		for(int j = hd[i]; j; j = nt[j]) {
    			int id = vr[j];
    			if(i == obj[id].l-1)
    			{
    				obj[id].ans1 -= BIT::ask(obj[id].a, obj[id].b);
    				obj[id].ans2 -= nbBIT::ask(obj[id].a, obj[id].b, obj[id].l - 1);
    			}
    			if(i == obj[id].r)
    			{
    				obj[id].ans1 += BIT::ask(obj[id].a, obj[id].b);
    				obj[id].ans2 += nbBIT::ask(obj[id].a, obj[id].b, obj[id].l - 1);
    			}
    		}
    	}
    	
    	for(int i=1; i<=m; ++i) cout << obj[i].ans1 << ' ' << obj[i].ans2 << '
    ';
    	
    	return 0;
    }
    
  • 相关阅读:
    Lucene in action 笔记 case study
    关于Restful Web Service的一些理解
    Lucene in action 笔记 analysis篇
    Lucene in action 笔记 index篇
    Lucene in action 笔记 term vector
    Lucene in action 笔记 search篇
    博客园开博记录
    数论(算法概述)
    DIV, IFRAME, Select, Span标签入门
    记一个较困难的SharePoint性能问题的分析和解决
  • 原文地址:https://www.cnblogs.com/tztqwq/p/14310582.html
Copyright © 2011-2022 走看看