• CF368B Sereja and Suffixes


    题目大意

    给出一个长度为 (n) 的序列 (a), 给出 (m) 个查询 (l) ,对于每个查询输出 ([l,n]) 的区间内不同数的个数。

    分析:

    将查询按照 (l) 的大小排序,从大到小的遍历,每次将 (>=) 当前 (l) 的位置的 (a[i]) 全部加入树状数组,让树状数组记录每个数是否出现过,每次的答案就是查询树状数组的总和。

    代码:

    #include <cstdio>
    #include <algorithm>
    const int MAX = 100010;
    #define lowbit(x) x & -x
    using namespace std;
    typedef pair<int, int> pa;
    int n, m, ans[MAX], a[MAX], c[MAX];
    pa l[MAX];
    const int lim = 1e5 + 1;
    //template
    template<class type>type _max(type _, type __) { return _ > __ ? _ : __; }
    template<class type>type _min(type _, type __) { return _ < __ ? _ : __; }
    template<class type>type _abs(type __) { return __ < 0 ? -__ : __; }
    template<class type>type _gcd(type __, type ___) { return (!___) ? __ : gcd(___, __ % ___); }
    template<class type>type _mod(type __, type ____) { if (__ >= 0 && __ < ____)return __; __ %= ____; if (__ < 0)__ += ____; return __; }
    template<class type>type _qpow(type __, type ___, type ____) { type ans = 1; for (; ___; ___ >>= 1, __ = _mod(__ * __, ____))if (___ & 1)ans = _mod(ans * __, ____); return ans; }
    //char buf[1 << 21], *p1 = buf, *p2 = buf;
    //inline int getc() {
    //	return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
    //}
    inline int r() {
    	register int x = 0; register char ch = getchar();
    	for (; ch < '0' || ch > '9'; ch = getchar());
    	for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
    	return x;
    }
    inline double r_db() {
    	double s = 0.0; int f = 1; char c = getchar();
    	while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
    	while (c >= '0' && c <= '9') { s = s * 10 + (c ^ 48); c = getchar(); }
    	if (c == '.') { int k = 10; c = getchar(); while (c >= '0' && c <= '9') { s += (double)(c ^ 48) / k; k *= 10; c = getchar(); } }
    	return s;
    }
    //以上的template可以忽略
    void add(int x) {
    	while (x <= lim) {
    		c[x]++;
    		x += lowbit(x);
    	}
    }
    int sum(int x) {
    	int ret = 0;
    	while (x) {
    		ret += c[x];
    		x -= lowbit(x);
    	}
    	return ret;
    }
    int main() {
    	while (~scanf("%d%d", &n, &m)) {
    		for (int i = 0; i < n; i++)
    			a[i] = r();
    		for (int i = 0; i < m; i++) {
    			l[i].first = r();
    			l[i].first--;
    			l[i].second = i;
    		}
    		sort(l, l + m);
    		int j = n - 1;
    		for (int i = m - 1; i >= 0; i--) {
    			while (j >= l[i].first) {
    				if (sum(a[j]) - sum(a[j] - 1) == 0)
    					add(a[j]);
    				j--;
    			}
    			ans[l[i].second] = sum(1e5);
    		}
    		for (int i = 0; i < m; i++)
    			printf("%d
    ", ans[i]);
    	}
    }
    
  • 相关阅读:
    虔诚的墓主人:组合数+数据结构
    DZY Loves Math II:多重背包dp+组合数学
    集合计数 :容斥原理
    「一本通 6.6 练习 8」礼物
    [bzoj3529][Sdoi2014]数表
    [专题总结]AC自动机
    6/14考试总结
    [无用]LNC李纳川的日常NC操作
    Linux下基本操作
    [ bzoj2820] YY的GCD
  • 原文地址:https://www.cnblogs.com/Lonely-233/p/13659030.html
Copyright © 2020-2023  润新知