HDU 5634-Rikka with Phi(線段樹區間更新)

Rikka with Phi

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 312    Accepted Submission(s): 103


Problem Description
Rikka and Yuta are interested in Phi function (which is known as Euler's totient function).

Yuta gives Rikka an array A[1..n] of positive integers, then Yuta makes m queries. 

There are three types of queries: 

1lr 

Change A[i] into φ(A[i]), for all i[l,r].

2lrx 

Change A[i] into x, for all i[l,r].

3lr 

Sum up A[i], for all i[l,r].

Help Rikka by computing the results of queries of type 3.

 

Input
The first line contains a number T(T100) ——The number of the testcases. And there are no more than 2 testcases with n>105

For each testcase, the first line contains two numbers n,m(n3×105,m3×105)

The second line contains n numbers A[i]

Each of the next m lines contains the description of the query. 

It is guaranteed that 1A[i]107 At any moment.
 

Output
For each query of type 3, print one number which represents the answer.
 

Sample Input
1 10 10 56 90 33 70 91 69 41 22 77 45 1 3 9 1 1 10 3 3 8 2 5 6 74 1 1 8 3 1 9 1 2 10 1 4 9 2 8 8 69 3 3 9
 

Sample Output
80 122 86
 



#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
const int maxn = 3e5 + 10;
const int phimaxn = 1e7 + 10;
int phi[phimaxn] = { 0 };
void getphi()
{
	phi[1] = 1;
	for (int i = 2; i < phimaxn; i++)
	{
		if (!phi[i])
		{
			for (int j = i; j < phimaxn; j += i)
			{
				if (!phi[j])
					phi[j] = j;
				phi[j] = phi[j] / i*(i - 1);
			}
		}
	}
}
LL sum[maxn << 2], lazy[maxn << 2];

void PushUp(int l, int r, int rt)
{
	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
	if (lazy[rt << 1] == lazy[rt << 1 | 1])
		lazy[rt] = lazy[rt << 1];
	else   
		lazy[rt] = 0;			//之前因爲這個沒寫所以錯了
}

void change(int rt, int l, int r)
{
	sum[rt] = lazy[rt] * (r - l + 1);
}

void PushDown(int l, int r, int rt)
{
	if (lazy[rt])
	{
		lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
		int m = (l + r) >> 1;
		change(rt << 1, l, m);
		change(rt << 1 | 1, m + 1, r);
		lazy[rt] = 0;
	}
}

void build(int l, int r, int rt)
{
	if (l == r)
	{
		scanf("%I64d", &sum[rt]);
		lazy[rt] = sum[rt];
		return;
	}
	lazy[rt] = sum[rt] = 0;
	int m = (l + r) >> 1;
	build(lson);
	build(rson);
	PushUp(l, r, rt);
}

void dophi(int L, int R, int l, int r, int rt)
{
	if (L <= l&&r <= R&&lazy[rt])
	{
		sum[rt] = (LL)(r - l + 1)*phi[lazy[rt]];
		lazy[rt] = (LL)phi[lazy[rt]];
		return;
	}
	PushDown(l, r, rt);
	int m = (l + r) >> 1;
	if (L <= m) dophi(L, R, lson);
	if (R > m) dophi(L, R, rson);
	PushUp(l, r, rt);
}

void update(int L, int R, int c, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		lazy[rt] = (LL)c;
		change(rt, l, r);
		return;
	}
	PushDown(l, r, rt);
	int m = (l + r) >> 1;
	if (L <= m) update(L, R, c, lson);
	if (R > m) update(L, R, c, rson);
	PushUp(l, r, rt);
}

LL query(int L, int R, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		return sum[rt];
	}
	PushDown(l, r, rt);
	LL ans = 0;
	int m = (l + r) >> 1;
	if (L <= m)
		ans += query(L, R, lson);
	if (R > m)
		ans += query(L, R, rson);
	PushUp(l, r, rt);
	return ans;
}

int main()
{
	getphi();
	int T;
	scanf("%d", &T);
	while (T--)
	{
		int n, m;
		scanf("%d%d", &n, &m);
		build(1, n, 1);
		for (int i = 0; i < m; i++)
		{
			int c, l, r, x;
			scanf("%d%d%d", &c, &l, &r);
			if (c == 1)
			{
				dophi(l, r, 1, n, 1);
			}
			else if (c == 2)
			{
				scanf("%d", &x);
				update(l, r, x, 1, n, 1);
			}
			else if (c == 3)
			{
				printf("%I64d\n", query(l, r, 1, n, 1));
			}
		}
	}
	return 0;
}


發佈了72 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章