Always cook mushroom
Time Limit: 10000/5000 MS (Java/others) memory limit: 65536/65536 K (Java/Others)
Total submission (s): 196 accepted submission (s): 54
Problem descriptionmatt has a company, always cook mushroom (ACM), which produces high-quality mushrooms.
ACM has a large field to grow their mushrooms. the field can be considered as a 1000*1000 grid where mushrooms are grown in grid points numbered from (1, 1) to (1000,100 0 ). because of humidity and sunshine, the productions in different grid points are not the same. further, the production in the grid points (X, Y) is (x + a) (Y + B) where A, B are two constant.
Matt, the owner of ACM has some queries where he wants to know the sum of the productions in a given scope (include the mushroom growing on the boundary ). in each query, the scope Matt asks is a right angled triangle whose apexes are (0, 0), (p, 0), (p, q) 1 <= P, Q <= 1000.
As the employee of ACM, can you answer Matt's queries?
Inputthe first line contains one integer T, indicating the number of test cases.
For each test case, the first line contains two integers: A, B (0 <= A, B <= 1000 ).
The second line contains one integer m (1 <= m <= 10 ^ 5), denoting the number of queries.
In the following M lines, the I-th line contains three integers a, B, x (1 <= A, B <= 10 ^ 6, 1 <= x <= 1000), denoting one apex of the given right angled triangle is (x, 0) and the slope of its base is (a, B ). it is guaranteed that the gird points in the given right angled triangle are all in valid area, numbered from (1, 1) to (1000,100 0 ).
Outputfor each test case, output m + 1 lines.
The first line contains "case # X:", where X is the case number (starting from 1)
In the following M lines, the I-th line contains one integer, denoting the answer of the I-th query.
Sample Input
20 033 5 82 4 71 2 31 233 5 82 4 71 2 3
Sample output
Case #1:1842170886Case #2:29012688200
Source2014 ACM/ICPC Asia Regional Beijing online
Theme
Given a mushroom field, only integer points from () to () can generate mushrooms. The mushroom yield of points (X, Y) is (x + a) (Y + B)
Given the two vertices of a right triangle and the slope of the Oblique Edge, we give them in the form of (a, B) to calculate the mushroom yield and in the triangle.
Solutions
Because there are a maximum of 1000*1000 = points, you can first find their slope and sort them, find the rank of each slope, and sort the query by X, discretization the slope, from top to bottom, add each vertex to the line tree from left to right. The query is actually a prefix and a sum. Process these points while processing the query.
This slope is updated to the maximum slope in each interval (equivalent to adding a line segment with the weight (x + a) (Y + B). This point is queried on a single point.
The habits of line tree are not very good ......
The tree array can also be used ......
#include <cstdio>#include <algorithm>#include <cstring>#define LL long longusing namespace std;inline int ReadInt(){ int flag=0; char ch=getchar(); int data=0; while (ch<'0'||ch>'9') { if (ch=='-') flag=1; ch=getchar(); } do { data=data*10+ch-'0'; ch=getchar(); }while (ch>='0'&&ch<='9'); return data;}int A,B;struct query{ int p,a,b,r;}q[100005];LL addv[2500010];LL ans[100005];struct node{ int a,b;}sl[1000005],tmp;int cmp2(node x,node y){ return (x.b*y.a<x.a*y.b);}int cmp(query x,query y){ return (x.p<y.p);}int cmp1(query x,query y){ return (x.r<y.r);}int t[1005][1005];int v;void update(int o, int L, int R,int le,int ri){ if (le<=L && ri>=R) addv[o]+=v; else { int M = (L + R)>>1; if (le<=M) update(o<<1,L,M,le,ri); if (ri>M) update(o<<1|1,M+1,R,le,ri); }}LL quer(int p,int x,int L,int R){ int M = (L + R)>>1; LL sum=addv[x]; if (L==R) return sum; if (p<=M) sum+=quer(p,x<<1,L,M); if (p>M) sum+=quer(p,x<<1|1,M+1,R); return sum;}int gcd(int x,int y){ if (x==0) return y; return gcd(y%x,x);}int main(){ int T,m,ca=0,cnt=0; for (int i=1;i<=1000;i++) for (int j=1;j<=1000;j++) if (gcd(i,j)==1) {sl[++cnt].a=i;sl[cnt].b=j;} sl[++cnt].a=1; sl[cnt].b=1000005; sl[0].a=1; sl[0].b=0; sort(sl+1,sl+1+cnt,cmp2); for (int i=1;i<=cnt;i++) { for (int j=1;(sl[i].a*j<=1000)&&(sl[i].b*j<=1000);j++) t[sl[i].a*j][sl[i].b*j]=i; } scanf("%d",&T); while (T--) { scanf("%d%d",&A,&B); scanf("%d",&m); for (int i=1;i<=m;i++) { q[i].r=i; q[i].a=ReadInt(); q[i].b=ReadInt(); q[i].p=ReadInt(); } memset(addv,0,sizeof addv); sort(q+1,q+m+1,cmp); int pt=0,r,c,le,ri,mid; for (int i=1;i<=m;i++) { while (q[i].p>=(pt/1000+1)&&pt<1000000) { pt++; r=(pt-1)/1000+1; c=(pt%1000)?(pt%1000):1000; v=(r+A)*(c+B); update(1,1,cnt,t[r][c],cnt); } tmp.a=q[i].a; tmp.b=q[i].b; le=0; ri=cnt; while (ri-le) { mid=(ri+le)>>1; if (cmp2(tmp,sl[mid])==0) le=mid+1; else ri=mid; } le--; ans[q[i].r]=quer(le,1,1,cnt); } printf("Case #%d:\n",++ca); for (int i=1;i<=m;i++) printf("%I64d\n",ans[i]); } return 0;}
[HDU 5032] 2014 Beijing Network Competition always cook mushroom discretization + offline line segment tree/tree Array