列表

详情


NC53272. 考试

描述

题目译自 JOISC 2019 Day1 T1「試験 / Examination
有N名学生参加了一个考试,考试包括数学和信息学两个科目。第i名学生在数学中获得了S_i分,在信息学中获得了T_i分。T教授和I教授将根据每名学生的得分决定是否挂他们的科。
  • T教授认为两门科目的得分都很重要,他认为只有数学考了至少A分,且信息学考了至少B分的学生可以通过考试。
  • I教授认为只有总得分才是重要的,他认为两门科目的总得分至少为C分的学生可以通过考试。
  • 只有按两名教授的标准都通过的学生才真的不会挂科。
现在给出Q组询问,每组询问的内容是,给定一个三元组(X_j,Y_j,Z_j),当时有多少学生能不挂科,你需要对每一组询问分别进行回答。

输入描述

从标准输入中读取数据。
第一行包括两个整数N,Q,表示学生人数和询问个数。
接下来N行,第i行两个整数S_iT_i,表示第i名学生的分数。
接下来Q行,第i行三个整数X_i,Y_i,Z_i,表示一组询问。

输出描述

输出数据到标准输出中。
输出Q行,每行一个整数,表示询问的答案(即有多少学生不挂科)。

示例1

输入:

5 4
35 100
70 70
45 15
80 40
20 95
20 50 120
10 10 100
60 60 80
0 100 100

输出:

2
4
1
1

说明:

当A=20,B=50,C=120时,只有第一名和第二名学生能通过考试,因此答案为2。
当A=10,B=10,C=100时,只有第一、二、四、五名学生能通过考试,因此答案为4。
当A=60,B=60,C=80时,只有第二名学生能通过考试,因此答案为1。
当A=0,B=100,C=100时,只有第一名学生能通过考试,因此答案为1。

示例2

输入:

10 10
41304 98327
91921 28251
85635 59191
30361 72671
28949 96958
99041 37826
10245 2726
19387 20282
60366 87723
95388 49726
52302 69501 66009
43754 45346 3158
25224 58881 18727
7298 24412 63782
24107 10583 61508
65025 29140 7278
36104 56758 2775
23126 67608 122051
56910 17272 62933
39675 15874 117117

输出:

1
3
5
8
8
3
3
3
5
6

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 273ms, 内存消耗: 13848K, 提交时间: 2020-04-19 19:10:20

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

const int N = 1e5 + 5;

const int inf = 2e9;

struct P {
	int x, y, z;
	P(){}
	P(int _x, int _y, int _z) {
		x = _x, y = _y, z = _z;
	}
};

int ans[N];

int cmpy(P a, P b) {
	return a.y < b.y;
}

int cmp(P a, P b) {
	if(a.x == b.x) return a.z < b.z;
	return a.x < b.x;
}

#define low(x) ((x) & -(x))
int t[N * 2];
void pla(int x, int y) {
	for(; x <= 2e5; x += low(x))
		t[x] += y;
}
int sum(int x) {
	int s = 0;
	for(; x; x -= low(x))
		s += t[x];
	return s;
}

struct Q {
	P d[N * 2]; int d0;
	void add(P a) { d[++ d0] = a;}
	void gg() {
		sort(d + 1, d + d0 + 1, cmpy);
		int id = 0, la = -inf;
		fo(i, 1, d0) {
			id += (i == 1 || d[i].y != la);
			la = d[i].y; d[i].y = id;
		}
		sort(d + 1, d + d0 + 1, cmp);
		memset(t, 0, sizeof t);
		fo(i, 1, d0) {
			if(d[i].z == -inf + 1 || d[i].z == -inf - 1) {
				pla(d[i].y, d[i].z + inf);
			} else {
				ans[d[i].z]	+= sum(d[i].y);
			}
		}
	}
} f, g, h;

int n, Q;
P a[N], b[N];

int main() {
	scanf("%d %d", &n, &Q);
	fo(i, 1, n) {
		scanf("%d %d", &a[i].x, &a[i].y);
		f.add(P(inf - a[i].x, inf - a[i].y, -inf + 1));
		g.add(P(inf - (a[i].x + a[i].y), inf - a[i].x, -inf + 1));
		h.add(P(inf - (a[i].x + a[i].y), a[i].y, -inf - 1));
	}
	fo(i, 1, Q) {
		scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].z);
		if(a[i].x + a[i].y >= a[i].z) {
			f.add(P(inf - a[i].x, inf - a[i].y, i));
		} else {
			g.add(P(inf - a[i].z, inf - a[i].x, i));
			h.add(P(inf - a[i].z, a[i].y - 1, i));
		}
	}
	f.gg(); g.gg(); h.gg();
	fo(i, 1, Q) pp("%d\n", ans[i]);
}

C++11(clang++ 3.9) 解法, 执行用时: 735ms, 内存消耗: 10984K, 提交时间: 2020-04-19 14:50:55

#include <iostream>
#include <algorithm>
#include <cmath>
#define pus push_back
#define pai pair<int,int>
#define fir first
#define sec second
#define M 1000005
#define Q 1000005
using namespace std;
int n,f,jsq=0;
pai p[M];
int v[M];
int a[Q];
bool cmp(pai x,pai y)
{
	return x.fir+x.sec<y.fir+y.sec;
}
struct nod{
	int a,b,c;
	int d;
}q[Q];
bool compare(nod x,nod y)
{
	return x.c<y.c;
}
int lob(int x) 
{
    return lower_bound(v+1,v+jsq+1,x)-v;
}
struct h{
    int t[M*2];
    int s;
    int lowbit(int x) 
	{
		return x&(-x);
    }
    void ins(int x,int y) 
	{
		while(x<=s) 
		{
	    	t[x]+=y;
	    	x+=lowbit(x);
		}
    }
    int query(int x) 
	{
		int ans=0;
		while(x>0) 
		{
	    	ans+=t[x];
	    	x-=lowbit(x);
		}
		return ans;
    }
}t[2];
int main()
{
	cin>>n>>f;
	for(int i=1;i<=n;i++)
	{
		cin>>p[i].fir>>p[i].sec;
		v[++jsq]=p[i].fir;
		v[++jsq]=p[i].sec;
	}
	sort(v+1,v+jsq+1);
	jsq=unique(v+1,v+jsq+1)-v-1;
	t[0].s=t[1].s=jsq;
	sort(p+1,p+n+1,cmp);
    for(int i=1;i<=f;i++) 
	{
		cin>>q[i].a>>q[i].b>>q[i].c;
		q[i].c=max(q[i].c,q[i].a+q[i].b);
		q[i].d=i;
		a[i]=n;
    }
    sort(q+1,q+f+1,compare);
	for(int i=1;i<=n;i++) 
	{
		t[0].ins(lob(p[i].fir),1);
		t[1].ins(lob(p[i].sec),1);
    }
    int ans=0;
    for(int i=1;i<=f;i++)
	{
		while(ans<n&&p[ans+1].fir+p[ans+1].sec<q[i].c) 
		{
	    	ans++;
	    	t[0].ins(lob(p[ans].fir),-1);
	    	t[1].ins(lob(p[ans].sec),-1);
		}
		a[q[i].d]-=ans;
		a[q[i].d]-=t[0].query(lob(q[i].a)-1);
		a[q[i].d]-=t[1].query(lob(q[i].b)-1);
    }
    for(int i=1;i<=f;i++)
	cout<<a[i]<<endl; 
	return 0;
} 

上一题