inlinevoidInput(){ read(n); for(int i = 1; i <= n; i++) { read(ax[i], ay[i]); a[i] = make_pair(ax[i], ay[i]); } for(int i = 1; i <= 9; i++) { read(c[i]), p[i] = i; } }
structpreST { int t[N], n; inlinevoidadd(int x){ t[x]++; } inlinevoidinit(){ for(int i = 1; i <= n; i++) t[i] += t[i - 1]; } inlineintfind(int x){ int p = lower_bound(t + 1, t + n + 1, x) - t; if(t[p] == x) return p; return0; } }tx, ty;
structBIT { vector<int > t[N]; inlinevoidadd(int x, int y){ for(int i = x; i <= tx.n; i += i & -i) t[i].push_back(y); } inlineintqry(int x, int y){ int ans = 0; for(int i = x; i >= 1; i -= i & -i) { ans += upper_bound(t[i].begin(), t[i].end(), y) - t[i].begin(); } return ans; } }bit;
inlinevoidCheck(){ int sx1 = c[p[1]] + c[p[4]] + c[p[7]]; int sx2 = sx1 + c[p[2]] + c[p[5]] + c[p[8]]; int sy1 = c[p[1]] + c[p[2]] + c[p[3]]; int sy2 = sy1 + c[p[4]] + c[p[5]] + c[p[6]]; int fx1 = tx.find(sx1); if(!fx1) return; int fx2 = tx.find(sx2); if(!fx2) return; int fy1 = ty.find(sy1); if(!fy1) return; int fy2 = ty.find(sy2); if(!fy2) return;
structBIT { ll c[M]; inlinevoidclear(){ memset(c, 0, sizeof(c)); } inlinevoidadd(int x, ll v){ for(int i = x; i < M; i += (i & (-i))) { c[i] += v; } } inline ll qry(int x){ ll ans = 0; for(int i = x; i >= 1; i -= (i & (-i))) { ans += c[i]; } return ans; } };
structBIT_2D { BIT c[M]; inlinevoidclear(){ for(int i = 0; i < M; i++) c[i].clear(); } inlinevoidadd(int x, int y, ll v){ for(int i = x; i < M; i += (i & (-i))) { c[i].add(y, v); } } inline ll qry(int x, int y){ ll ans = 0; for(int i = x; i >= 1; i -= (i & (-i))) { ans += c[i].qry(y); } return ans; } }bit2d;
这道题的思路是很经典的。题目让我们求星星左下角的点的数量,不难想到一个点左下面的点都是满足 x 坐标和 y 坐标都小于等于这个点的。但是同时维护两个最小值很麻烦,于是我们用排序。比如说我们按照 x 排序,那么第 $i$ 个点的左下角的点其实就是 $1\sim i-1$ 所有 y 坐标小于等于它的点的数量了,因为已经按照 x 排序,那么下标小的点 x 坐标就一定小,所以只需要记录小于等于当前点的 y 坐标的点即可。
inlinevoidInput(){ read(n); for(int i = 1; i <= n; i++) { read(a[i].first, a[i].second); a[i].first++, a[i].second++; } }
structBIT { int c[M]; inlinevoidadd(int x, int v){ for(int i = x; i < M; i += (i & (-i))) { c[i] += v; } } inlineintqry(int x){ int ans = 0; for(int i = x; i >= 1; i -= (i & (-i))) { ans += c[i]; } return ans; } }bit;
int cnt[N];
inlinevoidWork(){ sort(a + 1, a + n + 1); for(int i = 1; i <= n; i++) { cnt[bit.qry(a[i].second)]++; bit.add(a[i].second, 1); } for(int i = 0; i < n; i++) { printf("%d\n", cnt[i]); } }
intmain(){ int T = 1; while(T--) { Input(); Work(); } return0; }