HDU 4947 GCD Array

GCD Array

Time Limit: 11000/5500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 843    Accepted Submission(s):
205

Problem Description

Teacher Mai finds that many problems about arithmetic
function can be reduced to the following problem:

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

Author

xudyh

Source

2014
Multi-University Training Contest 8

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<cstring>
  4 #include<cstdlib>
  5 using namespace std;
  6 typedef __int64 LL;
  7
  8 const int maxn = 50000+3;
  9 const int INF = 2e5+3;
 10 LL p[maxn];
 11 bool s[INF];
 12 int prime[17985],len;
 13
 14 void Init()
 15 {
 16     len = 0;
 17     memset(s,false,sizeof(s));
 18     for(int i=2;i<INF;i++)
 19     {
 20         if(s[i]==true)continue;
 21         prime[++len] = i;
 22         for(int j=i+i;j<INF;j=j+i)
 23         s[j]=true;
 24     }
 25 }
 26 void add(int x,int n,int num1)
 27 {
 28     for(int i=x;i<=n;i=i+(i&(-i)))
 29     p[i] = p[i] + num1;
 30 }
 31 LL query(int x)
 32 {
 33     if(x==0)return 0;
 34     LL sum1 = 0;
 35     while(x)
 36     {
 37         sum1=sum1+p[x];
 38         x=x-(x&(-x));
 39     }
 40     return sum1;
 41 }
 42 int Q[5003],yz[1000],ylen,qlen;
 43 void init(int n)
 44 {
 45     ylen = qlen = 0;
 46     for(int i=1;prime[i]*prime[i]<=n;i++)
 47     {
 48         if(n%prime[i]==0)
 49         {
 50             while(n%prime[i]==0) n=n/prime[i];
 51             yz[++ylen] = prime[i];
 52         }
 53     }
 54     if(n!=1) yz[++ylen] = n;
 55     Q[0]=-1;
 56     for(int i=1;i<=ylen;i++)
 57     {
 58         int k = qlen;
 59         for(int j=0;j<=k;j++)
 60         Q[++qlen] = -1*Q[j]*yz[i];
 61     }
 62 }
 63 int main()
 64 {
 65     int n,m,hxl,d,v,size1,x,T=0;
 66     Init();
 67     while(scanf("%d%d",&n,&m)>0)
 68     {
 69         if(n==0&&m==0)break;
 70         memset(p,0,sizeof(p));
 71         printf("Case #%d:\n",++T);
 72         while(m--)
 73         {
 74             scanf("%d",&size1);
 75             if(size1==1)
 76             {
 77                 scanf("%d%d%d",&hxl,&d,&v);
 78                 if(hxl%d!=0)continue;
 79                 hxl = hxl /d;
 80                 int tom = n/d;
 81                 add(d,n,v);
 82                 init(hxl);
 83                 for(int i=1;i<=qlen;i++)
 84                 if(Q[i]<0) {
 85                     Q[i] = -Q[i];
 86                     if(Q[i]>tom)continue;
 87                     add(Q[i]*d,n,v);
 88                     }
 89                 else {
 90                     if(Q[i]>tom)continue;
 91                     add(Q[i]*d,n,-v);
 92                 }
 93             }
 94             else{
 95                 scanf("%d",&x);
 96                 LL sum1 = 0;
 97                 for(int i=1,la=0;i<=x;i=la+1){
 98                     la = x/(x/i);
 99                     sum1 = sum1 + (query(la)-query(i-1))*(x/i);
100                 }
101                 printf("%I64d\n",sum1);
102             }
103         }
104     }
105     return 0;
106 }
时间: 2024-10-07 07:38:02

HDU 4947 GCD Array的相关文章

HDU 3854 Glorious Array(树状数组)

题意:给一些结点,每个结点是黑色或白色,并有一个权值.定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大.给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前距离小于K的结点有多少对,K是一个定值. 思路:先求最初时候小于k的结点有多少对,然后每次改变颜色的时候,统计该点左侧和右侧各有多少同色和异色的结点(这一步使用树状数组),分别处理就行.另外需要预处理离某个结点最近的两个距离小于K的结点的位置. 代码写的略乱. #include<cstdio> #

HDU 1695 GCD 欧拉函数+容斥原理+质因数分解

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:在[a,b]中的x,在[c,d]中的y,求x与y的最大公约数为k的组合有多少.(a=1, a <= b <= 100000, c=1, c <= d <= 100000, 0 <= k <= 100000) 思路:因为x与y的最大公约数为k,所以xx=x/k与yy=y/k一定互质.要从a/k和b/k之中选择互质的数,枚举1~b/k,当选择的yy小于等于a/k时,可以

HDU 1695 GCD (数论-整数和素数,组合数学-容斥原理)

GCD Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output t

HDU 5726 GCD 区间GCD=k的个数

GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2742    Accepted Submission(s): 980 Problem Description Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). There ar

hdu 4497 GCD and LCM(排列组合)

题目:hdu 4497 GCD and LCM 题目大意:给出三个数的最大公约数,和最小公倍数,问这三个数的排列组合关系. 解题思路:最小公倍数/最大公约数 ==  三个数不同部分的乘积.这样来考虑的话,三个数都要有最大公约数的部分,其余的部分就是由LCM / GCD 里面的因子构成.这里面的因子可能会有 2 2 3 这样的情况, 不同的因子之间是不会相互干扰的,但是相同的会出现问题,因为,不能同时将相同的因子都放在三个位置上,这样最大公约数就的要乘上这个因子.然后对于单种因子来考虑的话,每种因

HDU 2588 GCD (欧拉函数)

GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1013    Accepted Submission(s): 457 Problem Description The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes writt

HDU 5164Matching on Array(AC自动机)

这是BC上的一道题,当时比赛没有做,回头看看题解,说是AC自动机,想着没有写过AC自动机,于是便试着抄抄白书的模板,硬是搞了我数个小时2000ms时限1800过了= = ! 这里就直接贴上BC的结题报告(#27):http://bestcoder.hdu.edu.cn/solutions.php 1003 Matching on Array 首先我们考虑m=1的情况.给定两个数组A={a1,a2,…,an}和B={b1,b2,…,bk},问B在A中出现了几次.令ci=ai+1ai,1≤i<n,同

HDU 5223 GCD

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5223 题面: GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 4    Accepted Submission(s): 0 Problem Description In mathematics, the greatest com

HDU 2588 GCD

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2588 解题思路: 本来的思路是枚举大于等于M的数S,若S|N,那么KS(KS<N)GCD(KS,N)>=M, 这样有重复的. 而这样有重复的: 若GCD(x,N)>=M. 设y=N/C,那么y的素因子有phi[i],phi[i+1]......., 那么GCD(x*phi[i],N)>=M, 而根据算术基本定理可知上述方法没有重复的. 那么ans=所有大于M的N的因子X的N/X的欧拉函数