HDU 4407 - Sum(容斥原理)
2015-01-31 15:09
309 查看
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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".
[align=left]Output[/align]
For each operation 1, output a single integer in one line representing the result.
[align=left]Sample Input[/align]
1
3 3
2 2 3
1 1 3 4
1 2 3 6
[align=left]Sample Output[/align]
7
0
题意:
1~n的数,两个操作:1.求出区间【x,y】中与c互质的数;2.将数列中的第x位的数改为c。
思路:
容斥原理。在操作一中将c的质因子存起来,在区间【x,y】中所有数的总和 - (整除两个质因子乘积的数和)+ (整除三个质因子乘积的数和)-(四个)。。。
注意在求总和的时候要用公式,不然会超时。
因为操作数只有1000以内,则可以使用数组将操作2的改变数的位置和数字存起来,记得之前改变过的位置如果再改变应该查找原来的那个数组位置,否则增加数组的个数,再操作一中遍历一遍。(一开始的思路:害怕每一次都遍历一遍会超时,所以试图使用lower_bound,但是此函数只对有序数列有用,使用时忽略了这一点!)
记得使用longlong,在这里wa了好久。
CODE:
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.
[align=left]Input[/align]
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".
[align=left]Output[/align]
For each operation 1, output a single integer in one line representing the result.
[align=left]Sample Input[/align]
1
3 3
2 2 3
1 1 3 4
1 2 3 6
[align=left]Sample Output[/align]
7
0
题意:
1~n的数,两个操作:1.求出区间【x,y】中与c互质的数;2.将数列中的第x位的数改为c。
思路:
容斥原理。在操作一中将c的质因子存起来,在区间【x,y】中所有数的总和 - (整除两个质因子乘积的数和)+ (整除三个质因子乘积的数和)-(四个)。。。
注意在求总和的时候要用公式,不然会超时。
因为操作数只有1000以内,则可以使用数组将操作2的改变数的位置和数字存起来,记得之前改变过的位置如果再改变应该查找原来的那个数组位置,否则增加数组的个数,再操作一中遍历一遍。(一开始的思路:害怕每一次都遍历一遍会超时,所以试图使用lower_bound,但是此函数只对有序数列有用,使用时忽略了这一点!)
记得使用longlong,在这里wa了好久。
CODE:
#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; ll chgid[1005], chgp[1005]; ll solve(ll l, ll r, ll cn) { ll S = (r + 1)*r/2 - (l*(l - 1)/2); vector<ll> p; for(int i = 2; i*i <= cn; ++i) { if(cn % i == 0) { p.push_back(i); while(cn % i == 0) cn /= i; } } if(cn > 1) p.push_back(cn); ll sum = 0, s = 0; for(ll msk = 1; msk < (1<<p.size()); ++msk) { ll mult = 1; int bits = 0; for(ll i = 0; i < p.size(); ++i) { if(msk & (1<<i)) { ++bits; mult *= p[i]; } } s = (mult + r/mult * mult)*(r/mult)/2 - (mult + (l-1)/mult * mult)*((l-1)/mult)/2; if(bits % 2 == 1) sum += s; else sum -= s; } return S - sum; } ll gcd(ll a, ll b) { if(b == 0) return a; return gcd(b, a%b); } int main() { //freopen("in", "r", stdin); ll T; scanf("%I64d", &T); while(T--) { memset(chgid, 0, sizeof(chgid)); memset(chgp, 0, sizeof(chgp)); ll n, m, x, y, c; ll g = 0; scanf("%I64d %I64d", &n, &m); while(m--) { int op; scanf("%d", &op); if(op == 1) { scanf("%I64d%I64d%I64d", &x, &y, &c); ll Sum = solve(x, y, c); for(int i = 0; i < g; ++i) { if(chgid[i] >= x && chgid[i] <= y) { if(gcd(chgid[i], c) == 1) Sum -= chgid[i]; if(gcd(chgp[i], c) == 1) Sum += chgp[i]; } } printf("%I64d\n",Sum); } else { scanf("%I64d%I64d", &x, &c); int i; for(i = 0; i < g; ++i) { if(chgid[i] == x) { chgp[i] = c; break; } } if(i == g) { chgid[g] = x; chgp[g++] = c; } } } } return 0; }
相关文章推荐
- hdu 4407 Sum(容斥原理)
- HDU 4407 Sum(12年金华网络赛-H题-容斥原理)
- hdu 4407 Sum 容斥原理
- HDU 4407 Sum (容斥原理)
- HDU-4407-Sum(容斥原理)
- HDU 4407 Sum(容斥原理+质因数分解)
- HDU 4407 Sum(容斥原理+状态压缩)
- HDU 4407 Sum(容斥原理)
- [容斥原理] hdu 4407 Sum
- Hdu 4407 Sum(容斥原理)
- hdu 4407 Sum 容斥原理
- hdu 4407 Sum(容斥原理)
- HDU 4407 Sum(容斥原理)
- HDU 4407 Sum ★(容斥原理)
- HDU 4407 Sum 容斥原理
- HDU 4407 Sum ★(容斥原理)
- HDU 4407 sum 容斥原理
- HDU 4407 SUM 容斥原理
- HDU 4407 Sum(12年金华 容斥原理)
- HDU 4407 Sum <容斥原理>