标签:
[BZOJ2850]巧克力王国
试题描述
输入
输出
输出m行,其中第i行表示第i个人所能接受的巧克力的美味值之和。
输入示例
3 3 1 2 5 3 1 4 2 2 1 2 1 6 1 3 5 1 3 7
输出示例
5 0 4
数据规模及约定
1 <= n, m <= 50000,1 <= 10^9,-10^9 <= a, b, x, y <= 10^9。
题解
题意就是统计一条给定直线下方或是上方的点权和。讨论一下 a 和 b 的正负性,然后判断一下一个矩形内是否可能有合法的点。
例如斜率为正的一条直线和一个矩形,要统计直线上方的点。若矩形左上角在直线上方则这个矩形可能有合法的点,若矩形右下角在直线上方则这个矩形内所有点都合法。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;
#define LL long long
const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
LL read() {
LL x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = Getchar(); }
return x * f;
}
#define maxn 50010
#define oo 2147483647
int n, m, Cur, ToT, root, lc[maxn], rc[maxn];
struct Node {
int x[2], mx[2], mn[2]; LL val, sum;
bool operator < (const Node& t) const { return x[Cur] < t.x[Cur]; }
} nodes[maxn];
void maintain(int o) {
int l = lc[o], r = rc[o];
for(int i = 0; i < 2; i++) {
nodes[o].mx[i] = max(max(nodes[l].mx[i], nodes[r].mx[i]), nodes[o].x[i]);
nodes[o].mn[i] = min(min(nodes[l].mn[i], nodes[r].mn[i]), nodes[o].x[i]);
}
nodes[o].sum = nodes[l].sum + nodes[r].sum + nodes[o].val;
return ;
}
void build(int& o, int L, int R, int cur) {
if(L > R){ o = 0; return ; }
int M = L + R >> 1; o = M;
Cur = cur; nth_element(nodes + L, nodes + M, nodes + R + 1);
build(lc[o], L, M - 1, cur ^ 1); build(rc[o], M + 1, R, cur ^ 1);
maintain(o);
return ;
}
bool tx, ty;
int a, b;
LL c;
bool all(int o) {
tx ^= 1; ty ^= 1;
int xx = tx ? nodes[o].mx[0] : nodes[o].mn[0], yy = ty ? nodes[o].mx[1] : nodes[o].mn[1];
tx ^= 1; ty ^= 1;
return ((LL)a * xx + (LL)b * yy < c);
}
bool has(int o) {
int xx = tx ? nodes[o].mx[0] : nodes[o].mn[0], yy = ty ? nodes[o].mx[1] : nodes[o].mn[1];
// printf("%d: %d %d %d %d\n", o, xx, yy, tx, ty);
return ((LL)a * xx + (LL)b * yy < c);
}
LL query(int o) {
if(!o) return 0;
LL ans = 0;
// printf("o: %d %d\n", o, root);
if(all(lc[o])) ans += nodes[lc[o]].sum;
else if(has(lc[o])) ans += query(lc[o]);
if(all(rc[o])) ans += nodes[rc[o]].sum;
else if(has(rc[o])) ans += query(rc[o]);
int xx = nodes[o].x[0], yy = nodes[o].x[1];
if((LL)a * xx + (LL)b * yy < c) ans += nodes[o].val;
return ans;
}
int main() {
nodes[0].mx[0] = nodes[0].mx[1] = -oo;
nodes[0].mn[0] = nodes[0].mn[1] = oo;
nodes[0].sum = 0;
n = read(); m = read(); LL sum = 0;
for(int i = 1; i <= n; i++) {
nodes[++ToT].x[0] = read(); nodes[ToT].x[1] = read(); nodes[ToT].val = read();
sum += nodes[ToT].val;
}
build(root, 1, n, 0);
while(m--) {
a = read(); b = read(); c = read();
if(a == 0 && b == 0) {
if(c > 0) printf("%lld\n", sum); else puts("0");
continue;
}
if(a == 0 && b > 0) tx = ty = 0;
if(a == 0 && b < 0) tx = 0, ty = 1;
if(a > 0 && b == 0) tx = ty = 0;
if(a < 0 && b == 0) tx = ty = 1;
if(a > 0 && b > 0) tx = ty = 0;
if(a < 0 && b > 0) tx = 1, ty = 0;
if(a > 0 && b < 0) tx = 0, ty = 1;
if(a < 0 && b < 0) tx = ty = 1;
printf("%lld\n", query(root));
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/5578194.html