树状数组+询问离线。一个优化是需要的,就是先对1000*1000个点先排序,而不是每次都生成这1000*1000个点然后和询问一起排序,那样会tle.
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
#define maxn 1200
#define ll long long
ll A,B;
struct Node
{
ll a,b;
int t;
ll v;
int id;
bool operator < (const Node& y) const{
if(b*y.a!=a*y.b) return b*y.a<a*y.b;
else return t<y.t;
}
}x[120000],y[1005000];
int tot,tot2;
ll ans[200000];
ll bit[maxn];
void add(int i,ll v){
while(i<=1000){
bit[i]+=v;
i+=i&(-i);
}
}
ll sum(int i){
ll ret=0;
while(i>0){
ret+=bit[i];
i-=i&(-i);
}
return ret;
}
int main()
{
int T;cin>>T;int ca=0;
tot2=0;
for(int i=1;i<=1000;++i){
for(int j=1;j<=1000;++j){
y[tot2].a=i;y[tot2].b=j;
y[tot2++].t=1;
}
}
sort(y,y+tot2);
while(T--){
scanf("%I64d%I64d",&A,&B);
tot=0;
int m;scanf("%d",&m);
int ai,bi,xi;
for(int i=0;i<m;++i){
scanf("%d%d%d",&ai,&bi,&xi);
x[tot].a=ai;
x[tot].b=bi;
x[tot].id=i;
x[tot].t=2;
x[tot++].v=xi;
}
sort(x,x+tot);
memset(bit,0,sizeof(bit));
int id=0;
for(int i=0;i<tot;++i){
while(id<tot2&&y[id]<x[i]){
add(y[id].a,(y[id].a+A)*(y[id].b+B));
++id;
}
ans[x[i].id]=sum(x[i].v);
}
printf("Case #%d:\n",++ca);
for(int i=0;i<m;++i){
printf("%I64d\n",ans[i]);
}
}
return 0;
}