相逢是问候

2017-09-09


Description

Informatik verbindet dich und mich.
信息将你我连结。(s:看到这个就感觉有毒
B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数。一共有m个操作,可以分为两种:0 l r表示将第l个到第r个数(al,al+1,...,ar)中的每一个数ai替换为c^ai,即c的ai次方,其中c是输入的一个常数,也就是执行赋值ai=c^ai1 l r求第l个到第r个数的和,也就是输出:sigma(ai),l<=i<=rai因为这个结果可能会很大,所以你只需要输出结果mod p的值即可。 


Input

第一行有三个整数n,m,p,c,所有整数含义见问题描述。
接下来一行n个整数,表示a数组的初始值。
接下来m行,每行三个整数,其中第一个整数表示了操作的类型。
如果是0的话,表示这是一个修改操作,操作的参数为l,r。
如果是1的话,表示这是一个询问操作,操作的参数为l,r。
1 ≤ n ≤ 50000, 1 ≤ m ≤ 50000, 1 ≤ p ≤ 100000000, 0 < c <p, 0 ≤ ai < p 


Output

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

Sample Input

4 4 7 2
1 2 3 4
0 1 4
1 2 4
0 1 4
1 1 3

Sample Output

0
3

1 40 19910626 2
0
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1 

in_put

1 2 4 16 65536 114181021832559013700558137005581370055813700558137005581370055813700558137005581370055813700558137005581370055813700558

out_put


考试时这个题感觉好神奇..当时某个学长讲的时候一脸mengbier,整个人都noip了..什么是φ?

欧拉函数裸题,一个数c在mod一个数的时候,在最多log2p次会不变....

所以线段树维护区间和,区间修改最小值;

修改时遍历到每一个节点,暴力修改每一个改变的值,因为到一定的次数不会变,所以记录一个tag代表这个区间一共修改了多少次...

当l==r时就是那个点修改次数...最多log2p次就不用改了,时间复杂度n*2log(n)。记住,欧拉不要乱mod,会出事的...

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll (long long)
#define LL long long
#define IN int
using namespace std;
const IN maxn=50000+99;
const IN N=10000+99;
int read(){int an=0,f=1;char ch=getchar();while(!('0'<=ch&&ch<='9')){if(ch=='-')f=-f;ch=getchar();}while('0'<=ch&&ch<='9'){an=an*10+ch-'0';ch=getchar();}return an*f;
}
IN phi[35],a[maxn],F;
IN n,m,p,c;
IN prime[maxn],isp[maxn],k,maxp;//k是质数个数,ips说明这是和数
struct saber{
IN sum,tag,l,r;
}tr[maxn<<2];
IN Phi(IN x){LL ans=x;for(IN i=1;i<=k && prime[i]*prime[i]<=x;i++){if(!(x%prime[i]))ans=ans*(prime[i]-1)/prime[i];while(!(x%prime[i]))x=x/prime[i];}if(x>1)ans=ans/x*(x-1);return ans;
}
void euler(){for(IN i=2;i<=N;i++){if(!isp[i])k++,prime[k]=i;for(IN j=1;j<=k;j++){if(i*prime[j]>N)break;isp[i*prime[j]]=1;if(!(i%prime[j]))break;}}phi[maxp]=p;while(phi[maxp]!=1)maxp++,phi[maxp]=Phi(phi[maxp-1]);maxp++;phi[maxp]=1;
}
void build(IN k,IN l,IN r){tr[k].l=l;tr[k].r=r;if(l==r){tr[k].sum=a[l];return ;}IN mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
IN ask(IN k,IN i,IN j){IN l=tr[k].l,r=tr[k].r;if(l==i&&r==j)return tr[k].sum;IN mid=(l+r)>>1;if(mid>=j)return ask(k<<1,i,j);else if(i>mid)return ask(k<<1|1,i,j);else return (ask(k<<1,i,mid)+ask(k<<1|1,mid+1,j))%p;
}
IN qw(LL k,IN mod){LL ans=1;LL s=c;while(k){if(k&1)ans*=s;k>>=1;s*=s;if(s>=mod)F=1,s%=mod;if(ans>=mod)F=1,ans%=mod;}return ans%mod;
}
LL work(LL a,LL t){LL tmp=a;if(tmp>phi[t])tmp=tmp%phi[t]+phi[t];for(IN i=t;i>0;i--){F=0;tmp=qw(tmp,phi[i-1]);if(F)tmp+=phi[i-1],F=0;}return tmp;
}
void change(IN k,IN i,IN j){if(tr[k].tag>=maxp)return;LL l=tr[k].l,r=tr[k].r;if(l==r){tr[k].tag++;tr[k].sum=work(a[l],tr[k].tag)%p;return;}IN mid=(l+r)>>1;if(mid>=j)change(k<<1,i,j);else if(i>mid)change(k<<1|1,i,j);else {change(k<<1,i,mid);change(k<<1|1,mid+1,j);}tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;tr[k].tag=min(tr[k<<1].tag,tr[k<<1|1].tag);
}
int main(){n=read();m=read();p=read();c=read();for(IN i=1;i<=n;i++)a[i]=read();euler();build(1,1,n);while(m){m--;IN x,y,z;x=read();y=read();z=read();if(x){printf("%lld\n",ask(1,y,z)%p);}else {change(1,y,z);}}return 0;
}

相逢是问候

by:s_a_b_e_r


表示考试结束学长讲题的时候一脸memgbier+1

欧拉定理+线段树维护

求ccc……a[i] %p的值

看上去一脸不可做,这要乘多少次

然而这个世界上存在着一个神奇的定理——欧拉定理EXT

a≡ax%φ(m)+φ(m)(mod m)

既然我们要求ccx(mod p)

不妨设d=c于是我们要求的就变成了cd

据欧拉定理有cd=cd%φ(p)+φ(p)(mod p)

即ccx=ccx%φ(p)+φ(p)(mod p)

看不清?放大一下

ccx=ccx%φ(p)+φ(p)(mod p)

标记的部分是不是很眼熟?

这部分又满足了欧拉定理

于是再抽一次φ变成

ccx%φ(φ(p))+φ(φ(p))%φ(p)+φ(p)(mod p)

这样一直抽下去,最后要%的东西会变成φ(φ(φ(φ(……p)))) (特别多个φ)

特别玄学的是这东西被φ多了就会变成1(据说最多log(p)次?)

然后就会出现x%1+1 = 0+1 = 1的状况

然后再对它修改就没什么用了,可以无视了

于是一发线段树维护每个点被修改了多少次

以及涉及欧拉的部分都不要乱%p,包括快速幂,容易出事qwq

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const int N=50099,SP=10099;
int pri[N],cp,phi[50],ci;
bool isp[N],f;
int n,m,p,c,a[N];
struct tree{
int l,r,tag;
ll sum;
}t[N<<2];
void update(int k){t[k].sum=t[k<<1].sum+t[k<<1|1].sum;t[k].tag=min(t[k<<1].tag,t[k<<1|1].tag);
}
void build(int k,int l,int r){t[k].l=l,t[k].r=r;if(l==r){t[k].sum=a[l];return;}int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);update(k);
}
int Phi(int x){//求欧拉函数int ans=x;for(int i=1;i<=cp&&pri[i]*pri[i]<=x;++i){if(!(x%pri[i]))ans=ans/pri[i]*(pri[i]-1);while(!(x%pri[i]))x/=pri[i];}if(x>1)ans=ans/x*(x-1);return ans;
}
void prime(){//欧拉筛素数for(int i=2;i<=SP;++i){if(!isp[i])pri[++cp]=i;for(int j=1;j<=cp;++j){if(i*pri[j]>N)break;isp[i*pri[j]]=1;if(i%pri[j]==0)break;}}phi[ci]=p;while(phi[ci]!=1)phi[++ci]=Phi(phi[ci-1]);phi[++ci]=1;
}
int kp(int x,int k,int mod){int ans=1;while(k){if(k&1){if(1ll*ans*x>=mod)f=1;ans=1ll*ans*x%mod;}if(1ll*x*x>=mod)f=1;x=1ll*x*x%mod;k>>=1;}return ans;
}
int C(int a,int x){//抽φ int tmp=a;if(tmp>phi[x])tmp=tmp%phi[x]+phi[x];//欧拉定理前提条件 for(int i=x;i>0;--i){f=0;tmp=kp(c,tmp,phi[i-1]);if(f==1)tmp+=phi[i-1];}return tmp;
}
void change(int k,int L,int R){if(t[k].tag>=ci)return;int l=t[k].l,r=t[k].r;if(l==r){t[k].sum=C(a[l],++t[k].tag);return;}int mid=(l+r)>>1;if(L<=mid)change(k<<1,L,R);if(R>mid)change(k<<1|1,L,R);update(k);
}
ll query(int k,int L,int R){int l=t[k].l,r=t[k].r;if(L<=l&&R>=r)return t[k].sum%p;if(r<L||l>R)return 0;return (query(k<<1,L,R)+query(k<<1|1,L,R))%p;
}
int main()
{scanf("%d%d%d%d",&n,&m,&p,&c);for(int i=1;i<=n;++i)scanf("%d",&a[i]);build(1,1,n);prime();for(int i=1;i<=m;++i){int type,l,r;scanf("%d%d%d",&type,&l,&r);if(!type)change(1,l,r);else printf("%lld\n",query(1,l,r)%p);}return 0;
}

verbinden

by:wypx


s:省选后听见有人说谁mo谁是真***,今天我就在ans膜了个p,╮(╯▽╰)╭

w:这说明了什么(笑)

s:%数学dalao

w:果然数学题还是要放⑨啊w

转载于:https://www.cnblogs.com/ck666/p/7499209.html

[bzoj 4869] [六省联考2017] 相逢是问候相关推荐

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

    好题啊! 调了一个中午,发现有一条语句 \(RE\) 了.在 \(windows\) 下没关系,\(linux\) 下有问题,大大的问题. while(phi[tot]!=1) phi[++tot]= ...

  2. BZOJ 4872 六省联考2017 分手是祝愿

    Problem BZOJ Solution 感觉dp状态的设置好巧妙啊 首先要明确的是怎么计算最小步数.就是直接从n到1扫,如果有亮着的,就按这个开关,模拟一下是O(nlnn)O(nln⁡n)O(n\ ...

  3. 六省联考2017 Day1

    目录 2018.3.18 Test T1 BZOJ.4868.[六省联考2017]期末考试 T2 T3 BZOJ.4870.[六省联考2017]组合数问题(DP 矩阵快速幂) 总结 考试代码 T1 T ...

  4. 【BZOJ4873】[六省联考2017]寿司餐厅(网络流)

    [BZOJ4873][六省联考2017]寿司餐厅(网络流) 题面 BZOJ 洛谷 题解 很有意思的题目 首先看到答案的计算方法,就很明显的感觉到是一个最大权闭合子图. 然后只需要考虑怎么构图就行了. ...

  5. P3749 [六省联考2017]寿司餐厅(最大权闭合子图变形)

    P3749 [六省联考2017]寿司餐厅 最大权闭合子图 有两种建图方式 下面a[i]a_[i]a[​i]表示寿司iii的编号 第二种建图其实就是把di,i也当成一个寿司而已d_{i,i}也当成一个寿 ...

  6. BZOJ 4872 luogu P3750 [六省联考2017]分手是祝愿

    4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec  Memory Limit: 512 MB [Submit][Status][Discuss] Description ...

  7. [BZOJ4873][六省联考2017]寿司餐厅(最大权闭合子图)

    4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 490  Solved: 350 [Submit][Stat ...

  8. 黑吉辽沪冀晋六省联考 2017 BZOJ 486848694870487148724873

    趁着网络上题解还不是很多,赶快怒写一发骗一下访问量 这套题在BZOJ上的题号是4868-4873. 感觉还不错,就是有一些题弄起来有一点小恶心-- 这套题的部分分给得都很多,很良心的QAQ BZOJ ...

  9. bzoj千题计划262:bzoj4868: [六省联考2017]期末考试

    http://www.lydsy.com/JudgeOnline/problem.php?id=4868 假设 最晚出成绩的是第i天 预处理 cnt[i] 表示 有多少个学生 期望出成绩的那一天 &l ...

最新文章

  1. sea.js学习网址和书籍
  2. 如何用python画数据图-用Python绘制地理图
  3. Print All JVM Flags
  4. 安全手册(初稿)[转]
  5. 最长上升子序列三种模板(n^2模板,二分模板,树状数组模板)
  6. 怎么查看mysql正在运行的语句_MySQL如何查询当前正在运行的SQL语句
  7. SQLyog备份与还原数据库
  8. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分
  9. 同步带轮介绍_Synchroflex丨红色GENIII同步带丨Mulco
  10. 读jQuery源码 jQuery.data
  11. [视频]K8飞刀 SQL注入点脱库演示教程
  12. ios9提取安装包ipa_iOS 应用降级与 IPA 安装包备份
  13. ICCV2021会议论文列表(可下载)
  14. python打印朱莉娅集合
  15. 软工网络15团队作业4——Alpha阶段敏捷冲刺之Scrum 冲刺博客(Day6)
  16. 你一事无成,还在那里傻乐
  17. GEE--LandTrendr
  18. 落单的数IV --- lintcode 824
  19. 关系数据库之关系数据结构及形式化定义
  20. 如何提高自己的学习能力

热门文章

  1. 树莓派4B装载ROS系统启动摄像头
  2. Node.js 使用webpack-dev-server工具运行项目实现自动打包编译的功能
  3. 基于Android的校园二手商品交易平台,基于Android校园二手交易网站毕业设计论文.doc...
  4. DAZ Studio Pro中文版
  5. PHP7天前的时间戳
  6. 结果集耗尽时,检查是否关闭结果集时常用sql
  7. amazeui学习笔记--css(HTML元素4)--图片image
  8. 老李分享:Web Services 组件 2
  9. Codeforces Round #335 (Div. 1)--C. Freelancer's Dreams 线性规划对偶问题+三分
  10. javascript中错误使用var造成undefined