zoukankan      html  css  js  c++  java
  • [洛谷P4688][Ynoi2016]掉进兔子洞

    题目大意:给定一个$n(nleqslant10^5)$序列,$m(mleqslant10^5)$个询问,每个询问给出$l_1,r_1,l_2,r_2,l_3,r_3$。令$s$为该三个区间的交集的大小,则输出$|[l_1,r_1]|+|[l_2,r_2]|+|[l_3,r_3]|−3|s|$

    题解:$|[l_1,r_1]|+|[l_2,r_2]|+|[l_3,r_3]|$这一部分比较好求,主要就是求$|s|$,$s$是这三个区间元素的并集,可以想到用$bitset$,但是$bitset$似乎只可以求有多少种相同元素,而不可以求有多少个相同元素,这时可以改一下离散化的方式,排序后不要去重,这时就可以用这个数和这个数现在已经出现的次数定下一个唯一确定位置。这样就可以完成求并集的过程了。

    这里可以用莫队来求每个数出现次数以及那一个元素出现的集合。但是发现空间复杂度是$O(dfrac{nm}{omega})$,开不下。可以把询问分成$3$次进行处理,就可以了

    卡点:把一个$maxm$打成了$maxn$,然后$RE$

    C++ Code:

    #include <algorithm>
    #include <bitset>
    #include <cstdio>
    #include <cctype>
    #include <iostream>
    namespace __IO {
    	namespace R {
    		int x, ch;
    		inline int read() {
    			while (isspace(ch = getchar()));
    			for (x = ch & 15; isdigit(ch = getchar()); ) x = x * 10 + (ch & 15);
    			return x;
    		}
    	}
    }
    using __IO::R::read;
    
    #define maxn 100010
    #define maxm 35000
    
    int n, m;
    int s[maxn], v[maxn];
    std::bitset<maxn> ans[maxm + 10], res;
    struct Query {
    	int l, r, id;
    	inline friend bool operator < (const Query &lhs, const Query &rhs) {
    		return lhs.l >> 8 == rhs.l >> 8 ? (lhs.l >> 8 & 1 ? lhs.r > rhs.r : lhs.r < rhs.r) : lhs.l < rhs.l;
    	}
    } q[maxm * 3 + 10];
    
    int tmpans[maxm + 10], cnt[maxn];
    
    inline void add(int x) {res.set(x + cnt[x]); cnt[x]++;}
    inline void del(int x) {cnt[x]--; res.reset(x + cnt[x]);}
    
    void solve() {
    	int tot = 0;
    	for (int i = 1; m && i < maxm; i++, m--) {
    		ans[i].set(); tmpans[i] = 0;
    		q[++tot].id = i, q[tot].l = read(), q[tot].r = read(), tmpans[i] += q[tot].r - q[tot].l + 1;
    		q[++tot].id = i, q[tot].l = read(), q[tot].r = read(), tmpans[i] += q[tot].r - q[tot].l + 1;
    		q[++tot].id = i, q[tot].l = read(), q[tot].r = read(), tmpans[i] += q[tot].r - q[tot].l + 1;
    	}
    	res.reset();
    	for (int i = 1; i <= n; i++) cnt[i] = 0;
    	int l = 1, r = 0;
    	std::sort(q + 1, q + tot + 1);
    	for (int i = 1; i <= tot; i++) {
    		while (r < q[i].r) add(s[++r]);
    		while (l > q[i].l) add(s[--l]);
    		while (r > q[i].r) del(s[r--]);
    		while (l < q[i].l) del(s[l++]);
    		ans[q[i].id] &= res;
    	}
    	const int M = tot / 3;
    	for (int i = 1; i <= M; i++) printf("%d
    ", tmpans[i] - ans[i].count() * 3);
    }
    
    int main() {
    	n = read(), m = read();
    	for (int i = 1; i <= n; i++) v[i] = s[i] = read();
    	std::sort(v + 1, v + n + 1);
    	for (int i = 1; i <= n; i++) s[i] = std::lower_bound(v + 1, v + n + 1, s[i]) - v;
    	while (m) solve();
    	return 0;
    }
    

      

  • 相关阅读:
    linux安装vsftpd服务器
    安装Twisted
    py文件转换为exe文件
    Python实现批量新建SecureCRT Session
    常见的字符编码
    心得 : 面向对象和面向过程的区别
    Apache配置HTTPS的过程小记
    关于oracle的sequence和trigger。
    oracle在drop表时要注意
    mysql中整数类型后面的数字,是不是指定这个字段的长度?比如int(11),11代表11个字节吗?
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10120966.html
Copyright © 2011-2022 走看看