description
我们定义一个非负整数是“好数”,当且仅当它符合以下条件之一:
1.这个数是0或1
2.所有小于这个数且与它互质的正整数可以排成一个等差数列例如,8就是一个好数,因为1,3,5,7排成了等差数列。
给出N个非负整数,然后进行如下三个操作:
1.询问区间[L,R]有多少个好数
2.将区间[L,R]内所有数对S取余(S≤1000000)
3.将第C个数更改为X
analysis
-
正解线段树+打表找规律
-
打表易知好数是222的幂或是质数,还有0,1,60,1,60,1,6
-
222的幂的等差数列公差为222,质数的公差为111,666例外
-
打一棵线段树,暴力修改是70pts70pts70pts,问题是取模不能区间操作
-
想一下,每个数被模以后一定小于等于原先的121\over 221,所以可以保证每个位置的数除了被修改就很少再被模
-
那么对于取模区间的操作,先O(log2n)O(\log_2n)O(log2n)找出组成区间的节点,再暴力向下寻找和修改
-
寻找的时候注意对于一段区间,如果区间的最大值已经大于模数,就可以returnreturnreturn了
-
所以跑得过去
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 100005
#define MAXNUM 1000005
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define O3 __attribute__((optimize("-O3")))
using namespace std;
ll a[MAXN],p[MAXNUM],tr[MAXN*4],mx[MAXN*4];
bool bz[MAXNUM];
ll n,m,tot;
O3 inline ll read()
{
ll x=0,f=1;char ch=getchar();

博客详细介绍了如何解决好数问题,利用线段树和打表的方法。好数定义为2的幂、质数或特定情况下的数字,如0、1、6。在给定的N个非负整数上,需要执行询问好数数量、区间取余和修改数值的操作。通过分析,发现取模后每个位置的数变化不大,因此使用线段树能有效处理区间操作,确保算法在限制时间内运行完成。
最低0.47元/天 解锁文章
513

被折叠的 条评论
为什么被折叠?



