816B. Karen and Coffee 前缀和思维 或 线段树

LINK

题意:给出n个[l,r],q个询问a,b,问被包含于[a,b]且这样的区间数大于k个的方案数有多少

思路:预处理所有的区间,对于一个区间我们标记其(左边界)++,(右边界+1)--这样就能通过前缀和维护小于某边界的区间个数了 这题也可以用线段树解,但显然不太合算

/** @Date    : 2017-07-01 10:02:30
  * @FileName: 816B 前缀和 线段树 二分.cpp
  * @Platform: Windows
  * @Author  : Lweleth (SoungEarlf@gmail.com)
  * @Link    : https://github.com/
  * @Version : $Id$
  */
#include <bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 2e5+20;
const double eps = 1e-8;


int n, k, q;
int cnt[N], ans[N];
int main()
{
	int l, r;
	while(cin >> n >> k >> q)
	{
		for(int i = 0; i < n; i++)
		{
			scanf("%d%d", &l, &r);
			cnt[l]++;
			cnt[r + 1]--;
		}
		for(int i = 1; i <= N; i++)
		{
			cnt[i] += cnt[i - 1];
			if(cnt[i] >= k)
				ans[i] = ans[i - 1] + 1;
			else ans[i] = ans[i - 1];
		}
		while(q--)
		{
			scanf("%d%d", &l, &r);
			printf("%d
", ans[r] - ans[l - 1]);
		}
	}
    return 0;
}
//标记l++ r--,获取前i个的标记和,大于k说明满足条件
//最终得到个数,前缀和表示到i个可行方案数(不用组合数)
原文地址:https://www.cnblogs.com/Yumesenya/p/7115001.html