题目大意:
有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为
能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。
http://wenku.baidu.com/link?url=1zHluup-GXHdByoQXhMRwRu22Uu15y4DztIr1_hKVxjHJmuLQF4_01UQhLEOR7RJIpsGyfD_5fXrx9DE7sY6JeukaNUY83In097GjUOmZ7K
ppt课件中讲的很仔细了
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 #define N 100000 5 #define ll long long 6 #define lowbit(x) x&(-x) 7 typedef pair<int , int> pii; 8 int sum[N+5] , mu[N+5] , prime[N+5] , tot; 9 bool check[N+5]; 10 pii f[N+5]; 11 12 void get_mu() 13 { 14 mu[1] = 1; 15 for(int i=1 ; i<=N ; i++) f[i].first=1 , f[i].second = i; 16 for(int i=2 ; i<=N ; i++){ 17 if(!check[i]){ 18 mu[i] = -1; 19 prime[tot++] = i; 20 } 21 for(int j=0 ; j<tot ; j++){ 22 if((ll)prime[j]*i>N) break; 23 check[i*prime[j]] = true; 24 if(i%prime[j]){ 25 mu[i*prime[j]] = -mu[i]; 26 }else break; 27 } 28 } 29 for(int i=2 ; i<=N ; i++) 30 for(int j=i ; j<=N ; j+=i) 31 f[j].first += i; 32 } 33 34 struct Query{ 35 int n , m , a , id; 36 void in(int i){scanf("%d%d%d" , &n , &m , &a) ; id=i;} 37 void reset(){if(n>m) swap(n,m);} 38 bool operator<(const Query &m)const { 39 return a<m.a; 40 } 41 }qu[N]; 42 43 int mxl , Q , ans[N]; 44 45 void add(int x , int v) 46 { 47 for(int i=x ; i<=mxl ; i+=lowbit(i)) sum[i]+=v; 48 } 49 50 int query(int x) 51 { 52 int ret = 0; 53 for(int i=x ; i>0 ; i-=lowbit(i)) ret += sum[i]; 54 return ret; 55 } 56 57 int find(int n , int m) 58 { 59 int ret = 0 , last; 60 for(int i=1 ; i<=n ; i=last+1){ 61 last = min(n/(n/i) , m/(m/i)); 62 ret += n/i*(m/i)*(query(last)-query(i-1)); 63 // cout<<n<<" "<<m<<" "<<ret<<" "<<query(last)<<" "<<query(i-1)<<endl; 64 } 65 return ret&(0x7fffffff); 66 } 67 68 void solve() 69 { 70 memset(sum , 0 , sizeof(sum)); 71 int index = 1 , cnt=0; 72 for(int i=1 ; i<=Q ; i++){ 73 while(f[index].first<=qu[i].a&&cnt<mxl){ 74 for(int j=f[index].second , k=1 ; j<=mxl ; j+=f[index].second ,k++){ 75 // cout<<index<<" "<<f[index].second<< " "<<f[index].first<<" "<<k<<" "<<mu[k]<<endl; 76 add(j , f[index].first*mu[k]); 77 } 78 index++; 79 if(f[index].second<=mxl) cnt++; 80 } 81 ans[qu[i].id] = find(qu[i].n , qu[i].m); 82 } 83 for(int i=1 ; i<=Q ; i++) printf("%d\n" , ans[i]); 84 } 85 86 int main() 87 { 88 //freopen("in.txt" , "r" , stdin); 89 get_mu(); 90 sort(f+1 , f+N+1); 91 while(~scanf("%d" , &Q)){ 92 mxl = 0; 93 for(int i=1 ; i<=Q ; i++) { 94 qu[i].in(i) , qu[i].reset(); 95 mxl = max(mxl , qu[i].n); 96 } 97 sort(qu+1 , qu+Q+1); 98 solve(); 99 } 100 return 0; 101 }
我还在坚持,我还未达到我所想,梦~~一直在