HDU 4676 Sum Of Gcd
Sum Of Gcd
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 405 Accepted Submission(s): 194
做了2013杭州的H题后回头看了下这题,发现之前根本不懂- -!
这题也是离线,好想要分块,就是那个sqrt(1.0*n)和lx[i].c=lx[i].l/d;和cmp
其他的用了个公式sigama(num[i],2)*euler[i];
公式中的num意义为能整除每个因子的数的个数
num[i],l to r 中i能整除i的个数,euler[i]为i的欧拉函数!
后面的是指num[vt[a[i]][j]],也就是能整除vt[a[i]][j]的个数和euler[vt[a[i]][j]];
这其实把num[i]*(num[i]-1)/2;这个等差求和的公式化回去,就相当于从0开始一个一个加
这题也要预处理因子,有那个因子就num[v]++;删的时候就num[v]--;便于整体相加求和!,然后按l排序,从左到右加过去,进行删补就可以了!
Problem Description
Given you a sequence of number a1, a2, ..., an, which is a permutation of 1...n.
You need to answer some queries, each with the following format:
Give you two numbers L, R, you should calculate sum of gcd(a[i], a[j]) for every L <= i < j <= R.
You need to answer some queries, each with the following format:
Give you two numbers L, R, you should calculate sum of gcd(a[i], a[j]) for every L <= i < j <= R.
Input
First line contains a number T(T <= 10),denote the number of test cases.
Then follow T test cases.
For each test cases,the first line contains a number n(1<=n<= 20000).
The second line contains n number a1,a2,...,an.
The third line contains a number Q(1<=Q<=20000) denoting the number of queries.
Then Q lines follows,each lines contains two integer L,R(1<=L<=R<=n),denote a query.
Then follow T test cases.
For each test cases,the first line contains a number n(1<=n<= 20000).
The second line contains n number a1,a2,...,an.
The third line contains a number Q(1<=Q<=20000) denoting the number of queries.
Then Q lines follows,each lines contains two integer L,R(1<=L<=R<=n),denote a query.
Output
For each case, first you should print "Case #x:", where x indicates the case number between 1 and T.
Then for each query print the answer in one line.
Then for each query print the answer in one line.
Sample Input
1
5
3 2 5 4 1
3
1 5
2 4
3 3
Sample Output
Case #1:
11
4
0
Source
Recommend
zhuyuanchen520 | We have carefully selected several similar problems for you: 4769 4767 4766 4765 4763
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <map> 3 #include <queue> 4 #include <vector> 5 #include <string> 6 #include <cmath> 7 #include <cstdio> 8 #include <cstring> 9 #include <cstdlib> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define maxn 20005 14 #define ll long long 15 #define INF 0x7fffffff 16 #define eps 1e-8 17 struct line{int l, r,p,c;}; 18 int n, m, k,x,y,res; 19 vector<int>p[maxn]; 20 line lx[maxn]; 21 int euler[maxn]; 22 int num[maxn]; 23 int ans[maxn]; 24 int a[maxn]; 25 void init(){ 26 for (int i = 1; i < maxn; i++)euler[i] = i; 27 for (int i = 2; i < maxn; i++) 28 if (euler[i] == i) 29 for (int j = i; j < maxn; j += i) 30 euler[j] = euler[j] / i*(i - 1); 31 for (int i = 1; i < maxn; i++){ 32 p[i].clear(); 33 for (int j = 1; j*j <= i; j++) 34 if (i%j == 0){ 35 p[i].push_back(j); 36 if (j*j!=i)p[i].push_back(i / j); 37 } 38 } 39 } 40 int query(int l, int r){ 41 for (int i = l; i < x; i++) 42 for (int j = 0; j < p[a[i]].size(); j++){ 43 k = p[a[i]][j]; 44 res += euler[k] * num[k]; 45 num[k]++; 46 } 47 for (int i = x; i < l; i++) 48 for (int j = 0; j < p[a[i]].size(); j++){ 49 k = p[a[i]][j]; 50 num[k]--; 51 res -= euler[k] * num[k]; 52 } 53 for (int i = r+1; i <= y; i++) 54 for (int j = 0; j < p[a[i]].size(); j++){ 55 k = p[a[i]][j]; 56 num[k]--; 57 res -= euler[k] * num[k]; 58 } 59 for (int i = y+1; i <= r; i++) 60 for (int j = 0; j < p[a[i]].size(); j++){ 61 k = p[a[i]][j]; 62 res += euler[k] * num[k]; 63 num[k]++; 64 } 65 x = l; y = r; 66 return res; 67 } 68 int cmp(line a, line b){ 69 if (a.c == b.c)return a.r < b.r; 70 return a.c < b.c; 71 } 72 int main(){ 73 int cas = 1; 74 init(); 75 int t; 76 scanf("%d", &t); 77 while (t--){ 78 scanf("%d", &n); 79 memset(num, 0, sizeof num); 80 for (int i = 1; i <= n; i++)scanf("%d", &a[i]); 81 scanf("%d", &m); 82 int d = sqrt(1.0*n); 83 for (int i = 0; i < m; i++){ 84 scanf("%d%d", &lx[i].l, &lx[i].r); 85 lx[i].c = lx[i].l / d; 86 lx[i].p = i; 87 } 88 sort(lx, lx + m, cmp); 89 res = 0; 90 x = lx[0].l; y = lx[0].r; 91 for (int i = x; i <= y; i++) 92 for (int j = 0; j < p[a[i]].size(); j++){ 93 k = p[a[i]][j]; 94 res += euler[k] * num[k]; 95 num[k]++; 96 } 97 ans[lx[0].p] = res; 98 for (int i = 1; i < m; i++)ans[lx[i].p] = query(lx[i].l, lx[i].r); 99 printf("Case #%d:\n", cas++); 100 for (int i = 0; i < m;i++)printf("%d\n", ans[i]); 101 } 102 return 0; 103 }
浙公网安备 33010602011771号