P3747 [六省联考2017]相逢是问候

题目描述

\(\text {Informatik verbindet dich und mich.}\)

信息将你我连结。

\(B\) 君希望以维护一个长度为 \(n\) 的数组,这个数组的下标为从 \(1\) 到 \(n\) 的正整数。

一共有 \(m\) 个操作,可以分为两种:

\(0\) \(l\) \(r\) 表示将第 \(l\) 个到第 \(r\) 个数\(( a_l,a_{l+1},...a_r )\)中的每一个数\(a_i\)替换为 \(c^{a_i}\),即 \(c\) 的 \(a_i\)次方,其中 \(c\) 是输入的一个常数,也就是执行赋值

$a_i = c^{a_i} $

\(1\) \(l\) \(r\) 求第 \(l\) 个到第 \(r\) 个数的和,也就是输出:

\(\sum_{i=l}^{r}a_i\)

因为这个结果可能会很大,所以你只需要输出结果 \(\mod p\) 的值即可。

输入输出格式

输入格式:

第一行有四个整数 \(n\), \(m\), \(p\), \(c\),所有整数含义见问题描述。

接下来一行 \(n\) 个整数,表示 \(a\) 数组的初始值。

接下来 \(m\) 行,每行三个整数,其中第一个整数表示了操作的类型。

如果是 \(0\) 的话,表示这是一个修改操作,操作的参数为 \(l\), \(r\)。

如果是 \(1\) 的话,表示这是一个询问操作,操作的参数为 \(l\), \(r\)。

输出格式:

对于每个询问操作,输出一行,包括一个整数表示答案 \(\mod p\) 的值。

说明

  • 对于 \(0\%\) 的测试点,和样例一模一样;

  • 对于另外 \(10\%\) 的测试点,没有修改;

  • 对于另外 \(20\%\) 的测试点,每次修改操作只会修改一个位置(也就是 \(l = r\)),并且每个位置至多被修改一次;

  • 对于另外 \(10\%\) 的测试点, \(p = 2\);

  • 对于另外 \(10\%\) 的测试点, \(p = 3\);

  • 对于另外 \(10\%\) 的测试点, \(p = 4\);

  • 对于另外 \(20\%\) 的测试点, \(n \le 100\); \(m \le 100\);

  • 对于 \(100\%\) 的测试点, \(1 \le n \le 50000 ; 1 \le m \le 50000 ; 1 \le p \le 100000000; 0 < c <p; 0 ≤ a_i < p\)。


好坑啊,写到自闭了。。

有结论

求\(c^{c^{{c..}^a}}\bmod p\)

递归的规模是\(\log_2p\)层

证明用一下扩展欧拉定理就行了

等价于\(p,\varphi(p),\varphi(\varphi(p))...\)有多少层。

对于\(p\)是偶数,至少减少一半

对于\(p\)是奇数,下一次一定是偶数


于是对每个位置,我们每次直接操作,暴力求改的值。

拿一颗平衡树维护还没有够次数的位置,拿树状数组维护。

修改操作的上界是\(O(nlogp)\)


考虑每次暴力求改的值,发现复杂度是\(O(log^2p)\)的

三个\(log\)应该比较难卡过去

扩展欧拉定理的层数不好优化,想办法优化快速幂

发现底数都是\(c\),可以分块预处理

对每个模数\(p\)预处理\(c^1\)$c^{10000}$,然后对$t=c^{10000}$再预处理一下$t^1$\(t^{10000}\)。

每次可以\(O(1)\)的把两块合并在一起


如果你一直wa3和wa20

可以试试这个数据

  1. 1 6 4 2
  2. 0
  3. 0 1 1
  4. 1 1 1
  5. 0 1 1
  6. 1 1 1
  7. 0 1 1
  8. 1 1 1

这里要注意扩展欧拉定理

\(a^t \equiv a^{min(t,t \ mod \ \varphi(p) + \varphi(p))} \ (mod \ p)\)

后面什么时候要加\(\varphi(p)\),什么时候不加


Code:

  1. #include <cstdio>
  2. #include <set>
  3. #define ll long long
  4. const int N=5e4+10;
  5. int n,m,cnt[N];
  6. ll p,c,las[N],a[N];
  7. std::set <int> s;
  8. std::set <int>::iterator it;
  9. ll quickpow(ll d,ll k,ll mod)
  10. {
  11. ll f=1;int flag=0;
  12. if(f>=mod) flag=1;
  13. f%=mod;
  14. while(k)
  15. {
  16. if(k&1)
  17. {
  18. if(f*d>=mod) flag=1;
  19. f=f*d%mod;
  20. }
  21. if(d*d>=mod) flag=1;
  22. d=d*d%mod;
  23. k>>=1;
  24. }
  25. return flag?f+mod:f;
  26. }
  27. ll phi(ll ba)
  28. {
  29. ll ans=ba;
  30. for(ll i=2;i*i<=ba;i++)
  31. {
  32. if(ba%i==0)
  33. {
  34. ans=ans*(i-1)/i;
  35. while(ba%i==0) ba/=i;
  36. }
  37. }
  38. if(ba!=1) ans=ans*(ba-1)/ba;
  39. return ans;
  40. }
  41. ll Mod[100],mxd;
  42. void get(ll mod)
  43. {
  44. if(mod==1)
  45. {
  46. Mod[++mxd]=mod;
  47. Mod[++mxd]=mod;
  48. return;
  49. }
  50. Mod[++mxd]=mod;
  51. get(phi(mod));
  52. }
  53. const int M=10000;
  54. ll S[100][M+10],T[100][M+10];
  55. void initpow()
  56. {
  57. for(int i=1;i<=mxd;i++)
  58. {
  59. for(int j=0;j<=M;j++)
  60. S[i][j]=quickpow(c,j,Mod[i]);
  61. ll t=quickpow(c,M,Mod[i])%Mod[i];
  62. for(int j=1;j<=M;j++)
  63. T[i][j]=quickpow(t,j,Mod[i])%Mod[i]+Mod[i];
  64. }
  65. }
  66. int De;
  67. ll Pow(ll d,int de)
  68. {
  69. return T[de][d/M]?(T[de][d/M]*S[de][d%M])%Mod[de]+Mod[de]:S[de][d%M];
  70. }
  71. ll dfs(ll ba,int de,int dep,ll mod)
  72. {
  73. if(dep==0) return ba>=mod?ba%mod+mod:ba;
  74. return Pow(dfs(ba,de+1,dep-1,Mod[de+1]),de);
  75. }
  76. ll t[N];
  77. void change(int pos,ll d)
  78. {
  79. while(pos<=n) t[pos]+=d,pos+=pos&-pos;
  80. }
  81. ll query(int pos)
  82. {
  83. ll sum=0;
  84. while(pos) sum+=t[pos],pos-=pos&-pos;
  85. return sum;
  86. }
  87. int main()
  88. {
  89. scanf("%d%d%lld%lld",&n,&m,&p,&c);
  90. for(int i=1;i<=n;i++)
  91. scanf("%lld",a+i),change(i,las[i]=a[i]),s.insert(i);
  92. get(p);
  93. initpow();
  94. for(int op,l,r,i=1;i<=m;i++)
  95. {
  96. scanf("%d%d%d",&op,&l,&r);
  97. if(op==0)
  98. {
  99. it=s.lower_bound(l);
  100. while(it!=s.end()&&*it<=r)
  101. {
  102. int pos=*it;
  103. De=++cnt[pos];
  104. ll d=dfs(a[pos],1,De,p);
  105. change(pos,d-las[pos]);
  106. las[pos]=d;
  107. it++;
  108. if(cnt[pos]==mxd-1) s.erase(pos);
  109. }
  110. }
  111. else
  112. printf("%lld\n",(query(r)-query(l-1))%p);
  113. }
  114. return 0;
  115. }

2018.10.10

洛谷 P3747 [六省联考2017]相逢是问候 解题报告的更多相关文章

  1. 洛谷P3747 [六省联考2017]相逢是问候

    传送门 题解 扩展欧拉定理. 线段树维护,已经全改到底了的节点就不管,不然暴力修改下去. //Achen #include<algorithm> #include<iostream& ...

  2. P3747 [六省联考2017]相逢是问候

    题意 如果对一个数操作\(k\)次,那么这个数会变成\(c^{c^{...^{a_i}}}\),其中\(c\)有\(k\)个. 根据P4139 上帝与集合的正确用法这道题,我们可以知道一个数不断变为自 ...

  3. [BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)

    4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1313  Solved: 471[Submit][Stat ...

  4. 洛谷P3750 [六省联考2017]分手是祝愿(期望dp)

    传送门 嗯……概率期望这东西太神了…… 先考虑一下最佳方案,肯定是从大到小亮的就灭(这个仔细想一想应该就能发现) 那么直接一遍枚举就能$O(nlogn)$把这个东西给搞出来 然后考虑期望dp,设$f[ ...

  5. 洛谷P3746 [六省联考2017]组合数问题

    题目描述 组合数 C_n^mCnm​ 表示的是从 n 个互不相同的物品中选出 m 个物品的方案数.举个例子,从 (1;2;3) 三个物品中选择两个物品可以有 (1;2);(1;3);(2;3) 这三种 ...

  6. 洛谷 P3745 [六省联考2017]期末考试

    题目描述 有 nnn 位同学,每位同学都参加了全部的 mmm 门课程的期末考试,都在焦急的等待成绩的公布. 第 iii 位同学希望在第 tit_iti​ 天或之前得知所有课程的成绩.如果在第 tit_ ...

  7. 洛谷P3749 [六省联考2017]寿司餐厅

    传送门 题解 这几道都是上周llj讲的题,题解也写得十分好了,所以直接贴了几个链接和代码. //Achen #include<algorithm> #include<iostream ...

  8. 洛谷P3745 [六省联考2017]期末考试

    传送门 题解 //Achen #include<algorithm> #include<iostream> #include<cstring> #include&l ...

  9. 洛谷 P3750 [六省联考2017]分手是祝愿

    传送门 题解 //Achen #include<algorithm> #include<iostream> #include<cstring> #include&l ...

随机推荐

  1. 搭建Maven私有仓库

    Nexus官网下载:Nexus Repository Manager OSS :https://www.sonatype.com/download-oss-sonatype 1.解压 $ tar -z ...

  2. macOs 使用Homebrew升级到MySQL 8系列之后,php无法连接解决方法

    当前时间2018-9-28 在使用brew install mysql 默认安装为 MySQL 8,但是使用php连接到数据库之后,出现了这种错误 (Unexpected server respose ...

  3. ES6笔记03-Set和Map数据结构

    ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值.Set本身是一个构造函数,用来生成Set数据结构. var s = new Set(); [2, 3, 5, 4, ...

  4. 【PHP项目】伪静态规则

    伪静态规则写法RewriteRule-htaccess详细语法使用 2016年03月30日 16:53:59 阅读数:20340 伪静态实际上是利用php把当前地址解析成另一种方法来访问网站,要学伪静 ...

  5. 【linux】【指令】systemctl 指令部分解读

    systemctl [OPTIONS...] {COMMAND} ... Query or send control commands to the systemd manager. -h --hel ...

  6. kivy学习二:做一个查询所在地区身份证前6位的小软件

    经过半个月的尝试,终于成功,记录下来备查! 做完之后发现有很多的问题没有解决,请大佬多批评指教! 强烈建议:学习KIVY的查看官方文档 需要用的知识: 1.字典的相关知识 2.kivy的下拉列表(Dr ...

  7. iOS常用控件-UIScrollView

    一. 常见属性 @property (nonatomic) CGPoint contentOffset;                      //记录UIScrollView滚动的位置 @pro ...

  8. 使用windows live writer写cnblog-1 安装wlr

    Writer:在本地编辑有声在色的博客内容,发布到你的网络博客!   离线安装文件下载地址:http://dx1.itopdog.cn/soft/wlsetup-all.rar 下了好几个离线版本的, ...

  9. 20145202课后题,2.56&9.16

    我做的是2.56题,要求我用多组值来测试show_bytes 9.16 主要是对局部性进行了一些分析. 实验楼里面是空的,我电脑上显示不出来,所以我就做了一些书上的习题. 第十章的所有题目都被学长做过 ...

  10. MVN settings.xml

    <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Soft ...