NC53272. 考试
描述
输入描述
从标准输入中读取数据。
第一行包括两个整数N,Q,表示学生人数和询问个数。
接下来N行,第i行两个整数和,表示第i名学生的分数。
接下来Q行,第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。示例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; }