洛谷 P3747 [六省联考2017]相逢是问候 解题报告
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 6 4 2
0
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
这里要注意扩展欧拉定理
\(a^t \equiv a^{min(t,t \ mod \ \varphi(p) + \varphi(p))} \ (mod \ p)\)
后面什么时候要加\(\varphi(p)\),什么时候不加
Code:
#include <cstdio>
#include <set>
#define ll long long
const int N=5e4+10;
int n,m,cnt[N];
ll p,c,las[N],a[N];
std::set <int> s;
std::set <int>::iterator it;
ll quickpow(ll d,ll k,ll mod)
{
ll f=1;int flag=0;
if(f>=mod) flag=1;
f%=mod;
while(k)
{
if(k&1)
{
if(f*d>=mod) flag=1;
f=f*d%mod;
}
if(d*d>=mod) flag=1;
d=d*d%mod;
k>>=1;
}
return flag?f+mod:f;
}
ll phi(ll ba)
{
ll ans=ba;
for(ll i=2;i*i<=ba;i++)
{
if(ba%i==0)
{
ans=ans*(i-1)/i;
while(ba%i==0) ba/=i;
}
}
if(ba!=1) ans=ans*(ba-1)/ba;
return ans;
}
ll Mod[100],mxd;
void get(ll mod)
{
if(mod==1)
{
Mod[++mxd]=mod;
Mod[++mxd]=mod;
return;
}
Mod[++mxd]=mod;
get(phi(mod));
}
const int M=10000;
ll S[100][M+10],T[100][M+10];
void initpow()
{
for(int i=1;i<=mxd;i++)
{
for(int j=0;j<=M;j++)
S[i][j]=quickpow(c,j,Mod[i]);
ll t=quickpow(c,M,Mod[i])%Mod[i];
for(int j=1;j<=M;j++)
T[i][j]=quickpow(t,j,Mod[i])%Mod[i]+Mod[i];
}
}
int De;
ll Pow(ll d,int de)
{
return T[de][d/M]?(T[de][d/M]*S[de][d%M])%Mod[de]+Mod[de]:S[de][d%M];
}
ll dfs(ll ba,int de,int dep,ll mod)
{
if(dep==0) return ba>=mod?ba%mod+mod:ba;
return Pow(dfs(ba,de+1,dep-1,Mod[de+1]),de);
}
ll t[N];
void change(int pos,ll d)
{
while(pos<=n) t[pos]+=d,pos+=pos&-pos;
}
ll query(int pos)
{
ll sum=0;
while(pos) sum+=t[pos],pos-=pos&-pos;
return sum;
}
int main()
{
scanf("%d%d%lld%lld",&n,&m,&p,&c);
for(int i=1;i<=n;i++)
scanf("%lld",a+i),change(i,las[i]=a[i]),s.insert(i);
get(p);
initpow();
for(int op,l,r,i=1;i<=m;i++)
{
scanf("%d%d%d",&op,&l,&r);
if(op==0)
{
it=s.lower_bound(l);
while(it!=s.end()&&*it<=r)
{
int pos=*it;
De=++cnt[pos];
ll d=dfs(a[pos],1,De,p);
change(pos,d-las[pos]);
las[pos]=d;
it++;
if(cnt[pos]==mxd-1) s.erase(pos);
}
}
else
printf("%lld\n",(query(r)-query(l-1))%p);
}
return 0;
}
2018.10.10
洛谷 P3747 [六省联考2017]相逢是问候 解题报告的更多相关文章
- 洛谷P3747 [六省联考2017]相逢是问候
传送门 题解 扩展欧拉定理. 线段树维护,已经全改到底了的节点就不管,不然暴力修改下去. //Achen #include<algorithm> #include<iostream& ...
- P3747 [六省联考2017]相逢是问候
题意 如果对一个数操作\(k\)次,那么这个数会变成\(c^{c^{...^{a_i}}}\),其中\(c\)有\(k\)个. 根据P4139 上帝与集合的正确用法这道题,我们可以知道一个数不断变为自 ...
- [BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)
4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1313 Solved: 471[Submit][Stat ...
- 洛谷P3750 [六省联考2017]分手是祝愿(期望dp)
传送门 嗯……概率期望这东西太神了…… 先考虑一下最佳方案,肯定是从大到小亮的就灭(这个仔细想一想应该就能发现) 那么直接一遍枚举就能$O(nlogn)$把这个东西给搞出来 然后考虑期望dp,设$f[ ...
- 洛谷P3746 [六省联考2017]组合数问题
题目描述 组合数 C_n^mCnm 表示的是从 n 个互不相同的物品中选出 m 个物品的方案数.举个例子,从 (1;2;3) 三个物品中选择两个物品可以有 (1;2);(1;3);(2;3) 这三种 ...
- 洛谷 P3745 [六省联考2017]期末考试
题目描述 有 nnn 位同学,每位同学都参加了全部的 mmm 门课程的期末考试,都在焦急的等待成绩的公布. 第 iii 位同学希望在第 tit_iti 天或之前得知所有课程的成绩.如果在第 tit_ ...
- 洛谷P3749 [六省联考2017]寿司餐厅
传送门 题解 这几道都是上周llj讲的题,题解也写得十分好了,所以直接贴了几个链接和代码. //Achen #include<algorithm> #include<iostream ...
- 洛谷P3745 [六省联考2017]期末考试
传送门 题解 //Achen #include<algorithm> #include<iostream> #include<cstring> #include&l ...
- 洛谷 P3750 [六省联考2017]分手是祝愿
传送门 题解 //Achen #include<algorithm> #include<iostream> #include<cstring> #include&l ...
随机推荐
- 【学时总结】◆学时·VI◆ SPLAY伸展树
◆学时·VI◆ SPLAY伸展树 平衡树之多,学之不尽也…… ◇算法概述 二叉排序树的一种,自动平衡,由 Tarjan 提出并实现.得名于特有的 Splay 操作. Splay操作:将节点u通过单旋. ...
- UVA_10820_send a table
When participating in programming contests, you sometimes face the following problem: You know how t ...
- scrapy--matplotlib
昨天晚上看了一些关于保存文件的相关资料,早早的睡了,白天根据网上查找的资料,自己再捡起来.弄了一上午就爬取出来了,开心!!!好吧,让我们开始 老规矩,先上图.大家也赶快行动起来 分类文件: 文件内co ...
- 45.VUE学习之--组件之父组件使用scope定义子组件模板样式结构实例讲解
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- select into from 和 insert into select
select into from 和 insert into select都是用来复制表, 两者的主要区别为: select into from 要求目标表不存在,因为在插入时会自动创建. inser ...
- java8之list集合中取出某一属性的方法
上代码 List<User> list = new ArrayList<User>(); User user1 = new User("第一位"," ...
- TouTiao开源项目 分析笔记20 问答详情
1.效果预览 1.1.效果预览,从问答列表开始 前面实现了从列表到内容. 这里主要讲解从内容到详情. 点击每一个回答内容,进入回答详情页面. 1.2.触发的点击事件 在WendaContentView ...
- ImageButton的坑 ImageButton 有问题
最近在用ImageButton,发现,我如果new ImageButton,并且 设置Warp_content,但是它并不会正真的warp,它会有一个边框. 不知道怎么回事. 后来,在代码里面使用Im ...
- 阿里巴巴Java开发规约Eclipse插件安装及使用
技术交流群:233513714 插件安装 环境:JDK1.8,Eclipse4+.有同学遇到过这样的情况,安装插件重启后,发现没有对应的菜单项,从日志上也看不到相关的异常信息,最后把JDK从1.6升级 ...
- BF算法(蛮力匹配算法)
将主串M指定位置和目标串S开始位置进行对比,如果相同将M的下一个字符和S的下一个字符对比,如果不同则M的下一个字符和S的开始位置对比,直到S中每一个字符和M中的连续字符串相等,否则不匹配. C#代码- ...