标签:tmp hdu gcd int mo 4947 include sum
GCD Array
Time Limit: 11000/5500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1765 Accepted Submission(s): 559
Maintain an array a with index from 1 to l. There are two kinds of operations:
1. Add v to ax for every x that gcd(x,n)=d.
2. Query
Input There are multiple test cases, terminated by a line "0 0".
For each test case, the first line contains two integers l,Q(1<=l,Q<=5*10^4), indicating the length of the array and the number of the operations.
In following Q lines, each line indicates an operation, and the format is "1 n d v" or "2 x" (1<=n,d,v<=2*10^5,1<=x<=l).
Output For each case, output "Case #k:" first, where k is the case number counting from 1.
Then output the answer to each query.
Sample Input 6 4 1 4 1 2 2 5 1 3 3 3 2 3 0 0
Sample Output Case #1: 6 7 析:长度为n的序列,初始为0,有2种操作: 1.输入n,d,v,对序列中元素ax加上v,其中x满足gcd(n,x) = d 2.输入x,查询1-x前缀和 给所有满足gcd(n,x) = d的数加上v 等价于[gcd(n,x) == d]*v 等价于 [gcd(n/d,x/d) == 1]*v 于是由莫比乌斯反演公式 ai = $$\sum_{d|i}^n$$ ,于是 ax += [gcd(n/d,x/d) == 1]*v = ax += $$\sum_{p|$$\frac{ n}{d },p|$$\frac{x }{d }}$$μ(p),发现枚举n/d的所有因数的d倍就是添加操作会影响的关于的那些f数组的位置 所以添加f(pd) += v∗μ(p),查询时,a[x] = $$\sum_{d|x}{f(d)}$$ = $$\sum_{i=1}^x$$ $$\sum_{d|x}{f(d)}$$,而$$\sum_{d|x}{f(d)}$$可对d进行枚举,即$$\sum_{d=1}^x$$ {$$\frac{x }{ d}f(d)}, 然后针对$$\frac{ x}{d }进行分块
#include <math.h> #include <vector> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #define ll long long using namespace std; const int N = 200005; int t, n, m, ans; int mo[N], prm[N], isP[N]; ll a[N]; vector<int>f[N]; void Mobius(){ ans = mo[1] = 1; for(int i = 2; i < N; i ++){ if(!isP[i]){ prm[ans++] = i; mo[i] = -1; } for(int j = 1; j < ans; j ++){ int tmp = i*prm[j]; if(tmp >= N)break; isP[tmp] = 1; if(i%prm[j] == 0){ mo[tmp] = 0; break; }else{ mo[tmp] = -mo[i]; } } } for(int i = 1; i < N; i ++){ for(int j = i; j < N; j += i) f[j].push_back(i); } } void add(int x, int v){ while(x <= n){ a[x] += v; x += x&(-x); } } ll sum(int x){ ll res = 0; while(x > 0){ res += a[x]; x -= x&(-x); } return res; } void update(int x, int d, int v){ if(x%d) return; x /= d; for(int i = 0; i < f[x].size(); i ++){ int q = f[x][i]; add(q*d, mo[q]*v); } } ll query(int x){ ll res = 0; for(int l = 1, r; l <= x; l = r+1){ r = x/(x/l); res += x/l*(sum(r)-sum(l-1)); } return res; } int main(){ Mobius(); int x, d, v, op, tot = 1; while(scanf("%d%d", &n, &m)){ if(n+m == 0) break; fill(a, a+n+1, 0); printf("Case #%d:\n", tot++); while(m--){ scanf("%d", &op); if(op&1){ scanf("%d%d%d", &x, &d, &v); update(x, d, v); }else{ scanf("%d", &x); printf("%I64d\n", query(x)); } } } return 0; }View Code
标签:tmp,hdu,gcd,int,mo,4947,include,sum 来源: https://www.cnblogs.com/microcodes/p/12823137.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。