仿佛现在已经完成了做题之前先开个坑的习惯,也许是为了逼迫自己去刷一些神题吧。。。然并卵,该剩的好多坑还是剩着呢。

【bzoj3813】一道线段树好题。已经把数论忘光光了。

欧几里德算法

扩展欧几里德算法概述

欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:
gcd函数就是用来求(a,b)的最大公约数的。
gcd函数的基本性质:
gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)
扩展欧几里德算法公式表述
gcd(a,b)=gcd(b,a mod b)
证明:a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a, d|b,而r = a - kb,因此d|r 
因此d是(b,a mod b)的公约数
假设d 是(b,a mod b)的公约数,则
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证
扩展算法
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在无数组整
数对 x,y ,使得 gcd(a,b)=ax+by。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,a>b>0 时
设 ax1+ by1= gcd(a,b);
bx2+ (a mod b)y2= gcd(b,a mod b);
根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则:ax1+ by1= bx2+ (a mod b)y2;
即:ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2;
也就是ax1+ by1 == ay2+ b(x2- [a / b] *y2);
根据恒等定理得:x1=y2; y1=x2- [a / b] *y2;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
 
贴了上面这么多内容,无非是想说明,若能找到ax+by==1,则(a,b)=1,即题中求出φ(i);
简述一下题目,询问一段区间内的累乘,求它的欧拉函数。
欧拉函数就是:φ(n) = n * (1 - 1 / p1) * (1 - 1 / p2) * (1 - 1 / p3) * (1 - 1 / p4)……*(1 - 1 / pn)

= n  / (p1 * p2 * p3 * …… * pn) * ((p1 - 1) * (p2 - 1) * (p3 - 1) * …… * (pn - 1))

这道题也是uoj的#38,uoj的blog上面有比较详细的解法,我看的陆爷的blog感觉写得蛮优美..

关于φ的求法有很多种,这里数字*π(pri[i]-1)/pri[i]即答案。只要60位记录一下状态即可。

呵呵哒,又get到一种逆元的新求法,不过没关系啦,考试的时候忘记了大不了写个quickmi

#include<cstdio>
#include<algorithm>
#define ll long long
#define mo 19961993
#define N 400050
using namespace std;
,n,tot=;
ll ni[],pri[];
struct node{
  int l,r;
  ll v;
}tree[][];
void calc(int f,int k,int val)
{
  )tree[f][k].v=val;
  else
  {
    tree[f][k].v=;
    ;i<=;i++)
      )tree[f][k].v+=1ll<<(i-);
  }
}
void update(int f,int p)
{
  )tree[f][p].v=tree[f][p+p].v*tree[f][p+p+].v%mo;
   ].v;
}
void build(int f,int p,int l,int r)
{
  tree[f][p].l=l;tree[f][p].r=r;;
  if(l==r){
    calc(f,p,);return;
  }
  build(f,p+p,l,mid);
  build(f,p+p+,mid+,r);
  update(f,p);
}
ll que(int f,int p,int x,int y)
{
  ;
  if(x==l&&r==y)return tree[f][p].v;
  if(y<=mid)return que(f,p+p,x,y);
   ,x,y);
    else{
      ),mid+,y)%mo;
       ,mid+,y);
    }
}
ll query(int xx,int yy)
{
  ll tmp1=que(,,xx,yy),tmp2=que(,,xx,yy);
  ;i<=;i++)
            ))) tmp1 = tmp1*(pri[i]-) % mo * ni[pri[i]] %mo;
  return tmp1;
}
void change(int p,int x,int y)
{
  ][p].l==x&&tree[][p].r==x){
    tree[][p].v=y;tree[][p].v=;
    ;i<=;i++)
     )tree[][p].v+=1ll<<(i-);
    return;
  }
  ][p].l+tree[][p].r)/;
  ,x,y);
  tree[][p].v=tree[][p+p].v*tree[][p+p+].v%mo;
  tree[][p].v=tree[][p+p].v|tree[][p+p+].v;
}
int main()
{
  ni[]=;
  int flag[N];
  ;i<M;i++)
  {
     ni[i] = -mo/i * ni[mo%i] % mo;
     ni[i]=(ni[i]+mo)%mo;
    ){tot++;pri[tot]=i;}
    ;j<=tot;j++)
    {
      if(i*pri[j]>M)break;
      flag[i*pri[j]]=;
      )break;
    }
  }
  build(,,,);
  build(,,,);
  scanf("%d",&n);
  ;i<=n;i++)
  {
    int op,x,y;
    scanf("%d%d%d",&op,&x,&y);
    )printf("%lld\n",query(x,y));
     ,x,y);
  }
} 

bzoj3813

这道题下午吃完午饭来写,困到最后只剩手在动也没啥知觉了。。。不写挂真是谢天谢地!

[bzoj3813]奇数园的更多相关文章

  1. [BZOJ3813] 奇数国 - 线段树

    3813: 奇数国 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 912  Solved: 508[Submit][Status][Discuss] ...

  2. BZOJ3813: 奇数国

    传送门 欧拉函数+线段树 因为只有60个素数,所以把状态压成long long的形式.用线段树维护区间和和区间和中有多少个质数.然后xjb搞搞就行了,具体参见代码. //BZOJ 3813 //by ...

  3. [bzoj3813] 奇数国 [线段树+欧拉函数]

    题面 传送门 思路 这题目是真的难读......阅读理解题啊...... 但是理解了以后就发现,题目等价于: 给你一个区间,支持单点修改,以及查询一段区间的乘积的欧拉函数值,这个答案对19961993 ...

  4. 【BZOJ3813】奇数国 线段树+欧拉函数

    [BZOJ3813]奇数国 Description 给定一个序列,每次改变一个位置的数,或是询问一段区间的数的乘积的phi值.每个数都可以表示成前60个质数的若干次方的乘积. Sample Input ...

  5. 【bzoj3813】: 奇数国 数论-线段树-欧拉函数

    [bzoj3813]: 奇数国 题意:给定一个序列,每个元素可以分解为最小的60个素数的形式.(x=p1^k1*p2^k2*......p60^k60)(p1=2,p2=3,…,p60=281) 支持 ...

  6. 【BZOJ3813】【清华集训2014】奇数国 线段树 数学

    题目描述 给你一个长度为\(n\)的数列,第\(i\)个数为\(a_i\).每个数的质因子都只有前\(60\)个质数.有\(q\)个询问,每次给你\(l,r\),求\(\varphi(\prod_{i ...

  7. 【bzoj3813】奇数国 线段树

    题目描述 给出一个长度为n的序列,每个数都可以由前60个质数的乘积表示,初始每个数都是3.支持两种操作:(1)修改一个数 (2)查询一段区间内所有数的乘积的欧拉函数值模19961993. 输入 第一行 ...

  8. 剑指Offer面试题:13.调整数组顺序使奇数位于偶数前面

    一.题目:调整数组顺序使奇数位于偶数前面 题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分. 例如有以下一个整数数组:12345 ...

  9. ZooKeeper 02 - ZooKeeper集群的节点为什么是奇数个

    目录 1 关于节点个数的说明 2 ZooKeeper集群的容错数 3 ZooKeeper集群可用的标准 4 为什么不能是偶数个节点 4.1 防止由脑裂造成的集群不可用 4.2 奇数个节点更省资源 4. ...

随机推荐

  1. September 7th 2016 Week 37th Wednesday

    Patience is bitter, but its fruit is sweet. 忍耐是痛苦的,但它的果实却是甜蜜的. However, many may give up before they ...

  2. 在linux中,rpm和yum有什么区别?

    rpm是由红帽公司开发的软件包管理方式,使用rpm我们可以方便的进行软件的安装.查询.卸载.升级等工作.但是rpm软件包之间的依赖性问题往往会很繁琐,尤其是软件由多个rpm包组成时.Yum(全称为 Y ...

  3. Centos以rpm方式进行安装MySql

    安装过很多次mysql了,却没好好总结过,每次安装完了都忘,下次还要重新Google,这次总结下,自己以后也有的查. 1.安装采用的的rpm包的方式,安装前要先看系统内是否安装了旧版本的MySql和m ...

  4. 添加本地jar到Maven库

    转自:http://dk05408.iteye.com/blog/2170986 上传: mvn install:install-file -Dfile=D:/workspace/p2p_server ...

  5. 比较原声socket 、GCDAsyncSocket

    原声socket NSInputStream 输入流(OC)NSOutputStream 输出流(OC)1:通过c语言的输入输出流CFReadStreamRef/CFWirteStreamRef(输入 ...

  6. Swift - 代码创建单例

    创建单例的方法 import UIKit //创建一个单例类 class SingleInstance: NSObject { //在单例类中,有一个用来共享数据的数组 var datas = [St ...

  7. hdu2030 汉字统计

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2030 解题思路:主要考察汉字的编码方式, 汉字机内码在计算机的表达方式的描述是,使用二个字节,汉字的每 ...

  8. zip 压缩文件 unzip查看zip压缩包内的内容

    [root@GitLab tmp]# zip -r new.zip ./*  adding: gitlab_key_file20161001-2668-1eu44mv (deflated 15%)  ...

  9. tengine-2.1.0 源码安装

    [root@localhost tengine-]# yum update -y [root@localhost tengine-]# yum install gcc gcc-c++ autoconf ...

  10. PHP实现执行定时任务的几种思路详解

    转:https://segmentfault.com/a/1190000002955509 PHP本身是没有定时功能的,PHP也不能多线程.PHP的定时任务功能必须通过和其他工具结合才能实现,例如Wo ...