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

【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. 带你熟悉CSS浮动

    一.概念理解 浮动:顾名思义先浮后动,浮动的对象会先漂浮起来,离开自己原来的位置(也就是所谓的脱离文档流),后动的意思是,它的后面的元素会向它原来的位置动起来. 二.注意事项 1.当元素有浮动属性时, ...

  2. asp.net 防止按钮重复提交

    1.将按钮属性设置如下: <asp:Button ID="btConfirm" runat="server" Text="Confirm&quo ...

  3. ios WaxPatch热更新原理

    以下是引用他人文章内容: 为什么需要 WaxPatch 很多情况下,已经在 AppStore 上线的应用需要紧急缺陷修复,此时便需要使用某些技术手段,使应用程序能够动态下载补丁,进行缺陷修复. 什么是 ...

  4. Redis自定义动态字符串(sds)模块(一)

    Redis开发者在开发过程中没有使用系统的原始字符串,而是使用了自定义的sds字符串,这个模块的编写是在文件:sds.h和sds.c文件中.Redis自定义的这个字符串好像也不是很复杂,远不像ngin ...

  5. iOS 判断第一个字符是数字还是汉字

       NSString *titleStr = @"琳小兮";  //先截取字符串,拿到第一个字符         NSString *firstStr = [titleStr s ...

  6. php PDO:数据访问抽象层

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. .NET开发工具之Excel导出公共类

    来源:Pino晨 链接:cnblogs.com/chenxygx/p/5954870.html 说明 最近接了一个任务,就是做一个列表的Excel导出功能.并且有很多页面都会使用这个功能. 导出的Ex ...

  8. MVC公开课 – 2.查询,删除 (2013-3-15广州传智MVC公开课)

    查询 /Controller/HomeController.cs /// <summary> /// 查询 文章 列表 /// </summary> /// <retur ...

  9. 与你相遇好幸运,Tippecanoe在Centos下の安装

    全新的CentOS 7 x86_64 安装编译工具 yum install -y gcc automake autoconf libtool make yum insyall -y gcc gcc-c ...

  10. C#委托(Action、Func、predicate)

    Predicate 泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法.此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素. public delegate boo ...