HDU5634-Rikka with Phi

本文介绍了一个涉及区间修改和查询的问题,主要包括将区间内的数值转换为欧拉函数值、统一区间内数值以及求区间和三种操作,并提供了一种利用线段树进行高效处理的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Rikka with Phi

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


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
 

Source
 

Recommend
hujie
 


题意:有3种区间操作:

1.是把区间内的所有数变成它的欧拉函数值

2.是把区间所有数都变成一个数x

3.是查询区间和

解题思路:线段树,维护区间内的数是否相同,区间更新即可


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;

int x[10000009], n, m;
LL sum[300009 << 2], lazy[300009 << 2];

void init()
{
	x[1] = 1;
	for (int i = 2; i < 10000009; i++) x[i] = i;
	for (int i = 2; i < 10000009; i++)
		if (x[i] == i)
			for (int j = i; j < 10000009; j += i) x[j] = x[j] / i*(i - 1);
}

void Push(int k, int l,int r)
{
	lazy[k << 1] = lazy[k << 1 | 1] = lazy[k];
	int mid = (l + r) >> 1;
	sum[k << 1] = (LL)lazy[k] * (mid - l + 1);
	sum[k << 1 | 1] = (LL)lazy[k] * (r - mid);
	lazy[k] = -1;
}

void Merge(int k)
{
	sum[k] = sum[k << 1] + sum[k << 1 | 1];
	lazy[k] = ((lazy[k << 1] == lazy[k << 1 | 1]) ? lazy[k << 1] : -1);
}

void build(int k, int l, int r)
{
	if (l == r) { scanf("%d", &lazy[k]); sum[k] = lazy[k]; return; }
	int mid = l + r >> 1;
	build(k << 1, l, mid);
	build(k << 1 | 1, mid + 1, r);
	Merge(k);
}

void update(int k, int l, int r, int ll, int rr, int val,int type)
{
	if (ll <= l&&r <= rr&&!type) { lazy[k] = val; sum[k] = (LL)(r - l + 1)*val; return; }
	if (ll <= l&&r <= rr&&type&&lazy[k] != -1) { lazy[k] = x[lazy[k]]; sum[k] = (LL)lazy[k] * (r - l + 1); return; }
	int mid = l + r >> 1;
	if (lazy[k]!=-1) Push(k, l, r);
	if (ll <= mid) update(k << 1, l, mid, ll, rr, val,type);
	if (rr > mid) update(k << 1 | 1, mid + 1, r, ll, rr, val,type);
	Merge(k);
}

LL getans(int k, int l, int r, int ll, int rr)
{
	if (ll <= l&&r <= rr) return sum[k];
	int mid = l + r >> 1;
	LL ans = 0;
	if (lazy[k]!=-1) Push(k, l, r);
	if (ll <= mid) ans += getans(k << 1, l, mid, ll, rr);
	if (rr > mid) ans += getans(k << 1 | 1, mid + 1, r, ll, rr);
	return ans;
}

int main()
{
	init();
	int t;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d%d", &n, &m);
		build(1, 1, n);
		while (m--)
		{
			int p, l, r, c;
			scanf("%d%d%d", &p, &l, &r);
			if (p == 1) update(1, 1, n, l, r,1,1);
			if (p == 2) scanf("%d", &c), update(1, 1, n, l, r, c,0);
			if (p == 3) printf("%lld\n", getans(1, 1, n, l, r));
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值