树状数组+询问离线。一个优化是需要的,就是先对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: ",++ca); for(int i=0;i<m;++i){ printf("%I64d ",ans[i]); } } return 0; }