• [洛谷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;
    }
    

      

  • 相关阅读:
    Eclipse常用插件汇总
    关于销售订单
    java下载文件的种方式
    左右对联
    链表
    Spring MVC 入门
    JAVA环境配置总结
    struts2 iterator判断奇偶
    保存页面的浏览记录
    心扬JS分页
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10120966.html
Copyright © 2020-2023  润新知