HYSBZ - 3813奇数国

  中文题,巨苟题,巨无敌苟!!首先是关于不相冲数,也就是互质数的处理,欧拉函数是可以求出互质数,但是这里的product非常大,最小都2100000,这是不可能实现的。所以我们要求互质数的话,得用到所有金额都用60个素数表示的这个条件。也就是x=p1a1xp2a2x...p60a60表示,pi是第i个素数,ai是对应的指数,这就变成了互质素求欧拉函数,可以先了解一下欧拉函数,引用一下境外大佬的博客欧拉函数的讲解我们需要用到这一条

p为质数

1. phi(p)=p-1   因为质数p除了1以外的因数只有p,故1至p的整数只有p与p不互质 

2. 如果i mod p = 0, 那么 phi(i * p)=phi(i) * p

3.若i mod p ≠0,  那么 phi( i * p )=phi(i) * ( p-1 ) 

  首先,如果我们要求phi(p1a1)的话,p1是质数,然后p1a1=p1a1-1*p1,而p1a1-1 mod p1=0,所以phi(p1a1)=phi(p1a1-1)*p1,又phi(p1a1-1)=phi(p1a1-2)*p1,一直到,phi(p1)=p1-1,所以phi(p1a1)=p1a1-1*(p1-1),

  然后求phi(p1a1*p2),p1a1 mod p2≠0,所以phi(p1a1*p2)=phi(p1a1)*(p2-1),再算phi(p1a1*p22),p1a1*p22 mod p2=0,所以phi(p1a1*p22)=phi(p1a1*p2)*p2,所以这样推下去的话,phi(p1a1*p2a2)=p1a1-1*(p1-1)*p2a2-1*(p2-1)

  我们可以得到phi(p1a1xp2a2x...p60a60)=p1a1-1*(p1-1)*p2a2-1*(p2-1)*...*p60a60-1*(p60-1)。

  因为它说这个国家的加法就是我们的乘法,所以我们可以用树状数组或者线段树来维护1~100000里存储的每个数对应的素数的次方,但第二苟的点来了,如果用线段树还好说,只要处理好懒标记就应该可以了,但是用树状数组,单点更新那里一不小心就会超时,超时了好几发后,我看学长的代码原来他们的树状数组也是9492ms险过的,先看AC代码,更新处是使用学长的处理。

 #include<cstdio>
#define lowb(x) x&(-x)
#define ll long long
const int N=;
const ll mod=;
int a[N+][]={},b[N],prime[]={
,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,
,,,,,,,,,,,};//我自己把素数打出来了
void updata(int x,int y,int z)
{
while(x<=N)
{
a[x][y]+=z;
x+=lowb(x);
}
}
int geta(int x,int y)
{
int ans=;
while(x)
{
ans+=a[x][y];
x-=lowb(x);
}
return ans;
}
void modify(int x,int y,int flag)
{
for(int i=;i<=;i++)//把价值转化成p1^a1+p2^a2+p3^a3+...+p60^a60的形式,然后存储指数ai
if(y%prime[i]==)
{
int z=;
while(y%prime[i]==)
{
z++;
y/=prime[i];
}
updata(x,i,flag*z);
}
}
ll pow(ll a,int b)
{
ll ans=;
a%=mod;
while(b)
{
if(b&)
ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=;
}
return ans;
}
int main()
{
int n,op,x,y,z;
scanf("%d",&n);
for(int i=;i<=N;i++)
{
b[i]=;
updata(i,,);//3是第二个素数,一开始每个都有3块钱
}
while(n--)
{
scanf("%d%d%d",&op,&x,&y);
if(op)
{
modify(x,b[x],-);//先减去原来的数
modify(x,y,);//再加上要修改的数
b[x]=y;
}
else
{
ll ans=;
for(int i=;i<=;i++)
{
z=geta(y,i)-geta(x-,i);
if(z)
ans=ans*pow(1ll*prime[i],z-)*(prime[i]-)%mod;
}
printf("%lld\n",ans);
}
}
return ;
}

学长好腻害哦

  学长的处理就是,保存好每一个原来的存款,然后每次更新时,先减去旧的存款然后再加上新的存款,而我的处理的话是

 for(int i=;i<=;i++)
{
z=;
while(y%prime[i]==)
{
z++;
y/=prime[i];
}
z=z-a[x][i];//原来新的指数和对旧的指数差值,正的说明要加上,负的说明要减去,0不需要更新
if(z!=)
  updata(x,i,z);
}

  我觉得我这样每个i只进行了一次更新,应该比学长的更快,然而T了,我觉得原因应该是在于如果z不是0的话,那么我的就是60遍每次都要从x节点更新到100000为止,但学长的看上去是跑了两边,但是if(y%prime[i]==0)这一句过滤掉很多没必要的更新,所以还是学长nb啊。。。

  至于线段树的做法,先留个坑,毕竟女同志能顶半边天。

HYSBZ - 3813 奇数国 欧拉函数+树状数组(线段树)的更多相关文章

  1. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

  2. 树状数组 && 线段树应用 -- 求逆序数

    参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...

  3. hdu1394(枚举/树状数组/线段树单点更新&区间求和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...

  4. hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu 5147 Sequence II【树状数组/线段树】

    Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...

  6. 「10.10」神炎皇(欧拉函数)·降雷皇(线段树,DP)·幻魔皇

    A. 神炎皇 很好的一道题,可能第一次在考场上遇到欧拉函数 题意:对于一个整数对 $(a,b)$,若满足 $a\times b\leq n$且$a+b$是$a\times b$的因子, 则称为神奇的数 ...

  7. 数据结构--树状数组&&线段树--基本操作

    随笔目的:方便以后对树状数组(BIT)以及基本线段树的回顾 例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 例题:hdu 1166 敌兵布阵 T ...

  8. hdu 1166 树状数组(线段树)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. 树状数组&线段树

    先是树状数组. 令这棵树的结点编号为C1,C2...Cn.令每个结点的值为这棵树的值的总和,那么容易发现: C1 = A1 C2 = A1 + A2 C3 = A3 C4 = A1 + A2 + A3 ...

随机推荐

  1. Java IO与NIO的总结、比较

    一.IO流总结 1.Java I/O主要包括如下3层次: 流式部分——最主要的部分.如:OutputStream.InputStream.Writer.Reader等 非流式部分——如:File类.R ...

  2. Java 多线程创建和线程状态

    一.进程和线程 多任务操作系统中,每个运行的任务是操作系统运行的独立程序. 为什么引进进程的概念? 为了使得程序能并发执行,并对并发执行的程序加以描述和控制. 因为通常的程序不能并发执行,为使程序(含 ...

  3. C#面向对象21 接口

    接口的规范: 1.接口是一种规范.只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员. 2.为了多态,接口不能被实例化,接口不new(不能创建对象) 3.接口中的成员不能加“访问修饰符”, ...

  4. 管家婆crm9.2 sp2升级问题求助及解决方案

    升级过程中发生如下问题: 弹出对话框1:升级完成,但是有错误产生. 弹出对话框2:升级数据库发生错误:An attempt was made to load an assembly from a ne ...

  5. luogu题解P4198楼房重建--线段树神操作

    题目链接 https://www.luogu.org/problemnew/show/P4198 分析 一句话题意,一条数轴上有若干楼房,坐标为\(xi\)的楼房有高度\(hi\),那么它的斜率为\( ...

  6. opencv3.3 CUDA 初学实例

    //swap.cu #include "cuda_runtime.h" #include "device_launch_parameters.h" #inclu ...

  7. Java ArrayList常用接口介绍及示例

    Java List 常用类型 类型 特征 ArrayList 随机访问元素快:中间插入与删除元素较慢:操作不是线程安全的 LinkedList 中间插入与删除操作代价较低,提供优化的顺序访问:随机访问 ...

  8. [yii\queue\Queue] [10] unknown job (attempt: 1, PID: 31167) is finished with error: yii\base\ErrorException: unserialize(): Error at offset 1922 of 65535 bytes

    网上的解决方案: 1. 报错场景:序列化字段中有中文,反序列化时有可能会出现报错. 错误原因:写入和取出数据库的时候,编码不同,中文符号长度不同,序列化中的长度就无法匹配. 解决办法:适合 php 5 ...

  9. idea中安装git后,代码颜色代表的含义

    idea中安装git以后,代码文件出现了不同的颜色 它们分别表示的含义: 绿色,已经加入控制暂未提交 红色,未加入版本控制 蓝色,加入,已提交,有改动 白色,加入,已提交,无改动 灰色:版本控制已忽略 ...

  10. linux命令详解——crontab

    基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 第4列表示 ...