Visible TreesTime
limit:2000/1000 MS (java/others) Memory limit:32768/32768 K (java/others)
Total submission (s): 1602 Accepted Submission (s): 661
Problem descriptionthere is many trees forming a m * n grid, the grid starts from (in). Farmer Sherlock is standing at (0,0) point. He wonders how many trees he can see.
If trees and Sherlock is in one line, Farmer Sherlock can only see the tree nearest to him.
Inputthe first line contains one integer t, represents the number of test cases. Then there is multiple test cases. For all test case there are one line containing the integers m and n (1≤m, n≤100000)
Outputfor each test case output one line represents the number of trees Farmer Sherlock can see.
Sample Input
21 12 3
Sample Output
15
Title translation: give you A (m,n) matrix, each point has a tree, you stand (0,0) point to see the Matrix, the front of the tree will block the back of the tree, ask you how many trees can be seen at this time! The idea of a knot: because it is standing (0,0), so the tree (x, y) and the tree that blocked it Y) There are some relationships, at this time and (0,0) three points collinear, so x/x = = y/y; therefore (x, Y) must have the number of conventions, so the point of arbitrary (A, b) as long as a B has an approximate, you can not see, on the other hand, a, b coprime must be seen, so the problem into the map , the first thing to think about is GCD, but the GCD is inevitable time-consuming, so you can use the principle of tolerance, the previous blog has introduced the use of the principle of tolerance to find M and 1-n how many coprime, then now is to seek 1-m in all the number and 1-n how many coprime, so the loop 1-n can!
#include <cstdio> #define LL long longint p[10],top;void getp (int v) { top=0; for (int i=2;i*i<=v;i++) { if (v%i==0) { p[top++]=i; while (v%i==0) v/=i; } } if (v>1) p[top++]=v;} LL NOP (int n,int t) { int i; LL num=0; for (i=t;i<top;i++) Num+=n/p[i]-nop (n/p[i],i+1); return num;} int main () { int t,m,n,i; LL sum; scanf ("%d", &t); while (t--) { scanf ("%d%d", &m,&n); Sum=n; for (i=2;i<=m;i++) { getp (i); sum+= (N-nop (n,0)); } printf ("%lld\n", sum);} }
To tell the truth code is very short, but still WA 3 times, the reason is very simple, nop forgot to write the return value, and GETP function, the while mistakenly written if, really do not know what to write the code when I think of what, after a day of quiet heart to change the other people's blog, found directly preprocessed prime table, Can save a part of the time, but memory consumption, the following code
#include <cstdio> #define LL long longint prime[100005][20];int cnt[100005]={0};void Init () {for (int i=2;i <=100000;i++) { if (cnt[i]) continue; prime[i][0]=i; Cnt[i]=1; for (int j=2;j*i<=100000;j++) prime[i*j][cnt[i*j]++]=i;} } ll DFS (int m,int n,int idx) { ll ret=0; for (int i=idx;i<cnt[m];i++) Ret+=n/prime[m][i]-dfs (m,n/prime[m][i],i+1); return ret;} int main () { Init (); int t,n,m; scanf ("%d", &t); while (t--) { scanf ("%d%d", &n,&m); LL ans=n; for (int i=2;i<=m;i++) ans+= (N-dfs (i,n,0)); printf ("%i64d\n", ans); } return 0;}
HDU 2841 Visible Trees "the principle of tolerance and repulsion"