Sum(hdu4407)

Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2974    Accepted Submission(s): 843

Problem Description

XXX is puzzled with the question below:

1, 2, 3, ..., n (1<=n<=400000) are placed in a line. There are m (1<=m<=1000) operations of two kinds.

Operation
1: among the x-th number to the y-th number (inclusive), get the sum of
the numbers which are co-prime with p( 1 <=p <= 400000).
Operation 2: change the x-th number to c( 1 <=c <= 400000).

For each operation, XXX will spend a lot of time to treat it. So he wants to ask you to help him.

Input

There are several test cases.
The first line in the input is an integer indicating the number of test cases.
For each case, the first line begins with two integers --- the above mentioned n and m.
Each the following m lines contains an operation.
Operation 1 is in this format: "1 x y p".
Operation 2 is in this format: "2 x c".

Output

For each operation 1, output a single integer in one line representing the result.

Sample Input

1
3 3
2 2 3
1 1 3 4
1 2 3 6

Sample Output

7
0

思路:容斥原理;

因为原数列是[1,n];所以数的和我们可以直接用求和公式;

然后m<1000;所以改变的最多不超过1000;我们用数组存改变,改变的位置会重复,这时后要覆盖,也就是数组中原先已有这个点,我们可以用map标记是否在数组中已有;

没有的话加入,有的话覆盖。

然后询问是[x,y]区间内与z互质的数的和,所以我们考虑分解z,那么素数打表。

然后容斥求在[x,y]与z互质数的和;然后再循环一遍改变,判断替换的数,和原来的数是否与z互质,原来的数互质的话减去原来的,改变的数互质的话,加上改变的数;

每个数的不同的质因数不超过9个;

复杂度(5120*m);

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<stdlib.h>
  5 #include<string.h>
  6 #include<queue>
  7 #include<map>
  8 typedef long long LL;
  9 using namespace std;
 10 bool prime[400005];
 11 int ans[400005];
 12 queue<int>que;
 13 int  cm[400005];
 14 int  ma[400005];
 15 int flag[2000];
 16 int gcd(int n,int m);
 17 map<int,int>my;
 18 int main(void)
 19 {
 20         int i,j,k;
 21         int p,q;
 22         int n,m;
 23         int x,y;
 24         int t;
 25         for(i=2; i<=2000; i++)
 26         {
 27                 if(!prime[i])
 28                 {
 29                         for(j=i; i*j<=400000; j++)
 30                         {
 31                                 prime[i*j]=true;
 32                         }
 33                 }
 34         }
 35         int cnt=0;
 36         for(i=2; i<=400000; i++)
 37         {
 38                 if(!prime[i])
 39                 {
 40                         ans[cnt++]=i;
 41                 }
 42         }
 43         scanf("%d",&k);
 44         while(k--)
 45         {      my.clear();
 46                 scanf("%d %d",&p,&q);
 47                 int bt=1;
 48                 for(i=0; i<=p; i++)
 49                         ma[i]=i;
 50                 while(q--)
 51                 {
 52                         scanf("%d",&n);
 53                         if(n==1)
 54                         {
 55                                 scanf("%d %d %d",&x,&y,&t);
 56                                 int r=0;
 57                                 int yy=0;
 58                                 int xy=t;
 59                                 if(x>y)swap(x,y);
 60                                 while(t>1)
 61                                 {
 62                                         if(r==0&&t%ans[yy]==0)
 63                                         {
 64                                                 r=1;
 65                                                 que.push(ans[yy]);
 66                                                 t/=ans[yy];
 67                                         }
 68                                         else if(r==1&&t%ans[yy]==0)
 69                                         {
 70                                                 t/=ans[yy];
 71                                         }
 72                                         else
 73                                         {
 74                                                 r=0;
 75                                                 yy++;
 76                                         }
 77                                 }
 78                                 x-=1;
 79                                 int ak=0;
 80                                 while(!que.empty())
 81                                 {
 82                                         cm[ak++]=que.front();
 83                                         que.pop();
 84                                 }
 85                                 LL sum1=0;
 86                                 LL sum2=0;
 87                                 for(i=1; i<=(1<<ak)-1; i++)
 88                                 {
 89                                         int nn=0;
 90                                         LL dp=1;
 91                                         for(j=0; j<ak; j++)
 92                                         {
 93                                                 if(i&(1<<j))
 94                                                 {
 95                                                         nn++;
 96                                                         dp*=(LL)cm[j];
 97                                                 }
 98                                         }
 99                                         if(nn%2)
100                                         {
101                                                LL ct=y/dp;
102                                                 LL qt=x/dp;
103                                                  LL ct1=ct+1;
104                                                  LL qt1=qt+1;
105                                                 sum1+=dp*ct1*ct/2;
106                                                 sum2+=dp*qt1*qt/2;
107                                         }
108                                         else
109                                         {
110                                                  LL ct=y/dp;
111                                                 LL qt=x/dp;
112                                                  LL ct1=ct+1;
113                                                  LL qt1=qt+1;
114                                                 sum1-=dp*ct1*ct/2;
115                                                 sum2-=dp*qt1*qt/2;
116                                         }
117                                 }  LL xc=1+x;LL yc=1+y;
118                                 LL ap1=(long long )(xc)*(long long)x/2;
119                                 LL ap2=(long long)(yc)*(long long)y/2;
120                                 ap2-=sum1;
121                                 ap1-=sum2;
122                                 ap2-=ap1;
123                                 for(j=1; j<bt; j++)
124                                 {
125                                         if(flag[j]>=x+1&&flag[j]<=y)
126                                         {
127                                                 int cp=gcd(xy,ma[flag[j]]);
128                                                 int cq=gcd(xy,flag[j]);
129                                                 if(cq==1)
130                                                         ap2-=flag[j];
131                                                 if(cp==1)
132                                                         ap2+=ma[flag[j]];
133                                         }
134                                 }
135                                 printf("%lld\n",ap2);
136                         }
137                         else
138                         {
139                                 scanf("%d %d",&x,&t);
140                                 if(my[x]==0)
141                                 {my[x]=1;flag[bt]=x;bt++;}
142                                 ma[x]=t;
143                         }
144                 }
145         }
146         return 0;
147 }
148 int gcd(int n,int m)
149 {
150         if(m==0)
151                 return n;
152         else if(n%m==0)
153                 return m;
154         else return gcd(m,n%m);
155 }
时间: 2024-10-12 23:49:40

Sum(hdu4407)的相关文章

hdu4407 Sum 容斥+暴力

http://acm.hdu.edu.cn/showproblem.php?pid=4407 Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1990    Accepted Submission(s): 564 Problem Description XXX is puzzled with the question below

HDU4407 Sum【容斥原理】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4407 题目大意: 刚开始有一个长度为N的序列,排列为{1.2.3.-.N}.下边是M个操作指令. 有两种操作: 操作1:给你三个整数 Left Right d  求出区间[Left,Right]上与整数d互素的数的和 操作2:给你两个整数 pos d  将第pos个位置上的数改为d. 解题思路: 求出区间[Left,Right]上与整数d互素的数的和可以用容斥定理求出,类似于HDU4135. 下边

LeetCode OJ - Sum Root to Leaf Numbers

这道题也很简单,只要把二叉树按照宽度优先的策略遍历一遍,就可以解决问题,采用递归方法越是简单. 下面是AC代码: 1 /** 2 * Sum Root to Leaf Numbers 3 * 采用递归的方法,宽度遍历 4 */ 5 int result=0; 6 public int sumNumbers(TreeNode root){ 7 8 bFSearch(root,0); 9 return result; 10 } 11 private void bFSearch(TreeNode ro

129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

Leetcode 494 Target Sum 动态规划 背包+滚动数据

这是一道水题,作为没有货的水货楼主如是说. 题意:已知一个数组nums {a1,a2,a3,.....,an}(其中0<ai <=1000(1<=k<=n, n<=20))和一个数S c1a1c2a2c3a3......cnan = S, 其中ci(1<=i<=n)可以在加号和减号之中任选. 求有多少种{c1,c2,c3,...,cn}的排列能使上述等式成立. 例如: 输入:nums is [1, 1, 1, 1, 1], S is 3. 输出 : 5符合要求5种

31.SUM() 函数

SUM() 函数 SUM 函数返回数值列的总数(总额). SQL SUM() 语法 SELECT SUM(column_name) FROM table_name SQL SUM() 实例 我们拥有下面这个 "Orders" 表: O_Id OrderDate OrderPrice Customer 1 2008/12/29 1000 Bush 2 2008/11/23 1600 Carter 3 2008/10/05 700 Bush 4 2008/09/28 300 Bush 5

1305 Pairwise Sum and Divide

基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 有这样一段程序,fun会对整数数组A进行求值,其中Floor表示向下取整: fun(A) sum = 0 for i = 1 to A.length for j = i+1 to A.length sum = sum + Floor((A[i]+A[j])/(A[i]*A[j])) return sum 给出数组A,由你来计算fun(A)的结果.例如:A = {1, 4, 1},fun(A) = [5/4] + [

Java [Leetcode 303]Range Sum Query - Immutable

题目描述: Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. Example: Given nums = [-2, 0, 3, -5, 2, -1] sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3 Note: You may assume that the ar

LeetCode 303. Range Sum Query - Immutable

求数组nums[i,j]的和 思路:另开一sum数组,sum[i]为nums[0,i]的和,所以nums[i,j] = sum[j] - sum[i-1] 1 class NumArray { 2 public: 3 vector<int> sum; 4 NumArray(vector<int> &nums) { 5 sum.resize(nums.size(), 0); 6 sum[0] = nums[0]; 7 int len = nums.size(); 8 for(