[bzoj 4869] [六省联考2017] 相逢是问候
相逢是问候
2017-09-09
Description
Input
Output
Sample Input
1 2 3 4
0 1 4
1 2 4
0 1 4
1 1 3
Sample Output
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
ax ≡ax%φ(m)+φ(m)(mod m)
既然我们要求ccx(mod p)
不妨设d=cx 于是我们要求的就变成了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] 相逢是问候相关推荐
- [六省联考2017]相逢是问候(线段树+拓展欧拉定理)
好题啊! 调了一个中午,发现有一条语句 \(RE\) 了.在 \(windows\) 下没关系,\(linux\) 下有问题,大大的问题. while(phi[tot]!=1) phi[++tot]= ...
- BZOJ 4872 六省联考2017 分手是祝愿
Problem BZOJ Solution 感觉dp状态的设置好巧妙啊 首先要明确的是怎么计算最小步数.就是直接从n到1扫,如果有亮着的,就按这个开关,模拟一下是O(nlnn)O(nlnn)O(n\ ...
- 六省联考2017 Day1
目录 2018.3.18 Test T1 BZOJ.4868.[六省联考2017]期末考试 T2 T3 BZOJ.4870.[六省联考2017]组合数问题(DP 矩阵快速幂) 总结 考试代码 T1 T ...
- 【BZOJ4873】[六省联考2017]寿司餐厅(网络流)
[BZOJ4873][六省联考2017]寿司餐厅(网络流) 题面 BZOJ 洛谷 题解 很有意思的题目 首先看到答案的计算方法,就很明显的感觉到是一个最大权闭合子图. 然后只需要考虑怎么构图就行了. ...
- P3749 [六省联考2017]寿司餐厅(最大权闭合子图变形)
P3749 [六省联考2017]寿司餐厅 最大权闭合子图 有两种建图方式 下面a[i]a_[i]a[i]表示寿司iii的编号 第二种建图其实就是把di,i也当成一个寿司而已d_{i,i}也当成一个寿 ...
- BZOJ 4872 luogu P3750 [六省联考2017]分手是祝愿
4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec Memory Limit: 512 MB [Submit][Status][Discuss] Description ...
- [BZOJ4873][六省联考2017]寿司餐厅(最大权闭合子图)
4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 490 Solved: 350 [Submit][Stat ...
- 黑吉辽沪冀晋六省联考 2017 BZOJ 486848694870487148724873
趁着网络上题解还不是很多,赶快怒写一发骗一下访问量 这套题在BZOJ上的题号是4868-4873. 感觉还不错,就是有一些题弄起来有一点小恶心-- 这套题的部分分给得都很多,很良心的QAQ BZOJ ...
- bzoj千题计划262:bzoj4868: [六省联考2017]期末考试
http://www.lydsy.com/JudgeOnline/problem.php?id=4868 假设 最晚出成绩的是第i天 预处理 cnt[i] 表示 有多少个学生 期望出成绩的那一天 &l ...
最新文章
- sea.js学习网址和书籍
- 如何用python画数据图-用Python绘制地理图
- Print All JVM Flags
- 安全手册(初稿)[转]
- 最长上升子序列三种模板(n^2模板,二分模板,树状数组模板)
- 怎么查看mysql正在运行的语句_MySQL如何查询当前正在运行的SQL语句
- SQLyog备份与还原数据库
- 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分
- 同步带轮介绍_Synchroflex丨红色GENIII同步带丨Mulco
- 读jQuery源码 jQuery.data
- [视频]K8飞刀 SQL注入点脱库演示教程
- ios9提取安装包ipa_iOS 应用降级与 IPA 安装包备份
- ICCV2021会议论文列表(可下载)
- python打印朱莉娅集合
- 软工网络15团队作业4——Alpha阶段敏捷冲刺之Scrum 冲刺博客(Day6)
- 你一事无成,还在那里傻乐
- GEE--LandTrendr
- 落单的数IV --- lintcode 824
- 关系数据库之关系数据结构及形式化定义
- 如何提高自己的学习能力
热门文章
- 树莓派4B装载ROS系统启动摄像头
- Node.js 使用webpack-dev-server工具运行项目实现自动打包编译的功能
- 基于Android的校园二手商品交易平台,基于Android校园二手交易网站毕业设计论文.doc...
- DAZ Studio Pro中文版
- PHP7天前的时间戳
- 结果集耗尽时,检查是否关闭结果集时常用sql
- amazeui学习笔记--css(HTML元素4)--图片image
- 老李分享:Web Services 组件 2
- Codeforces Round #335 (Div. 1)--C. Freelancer's Dreams 线性规划对偶问题+三分
- javascript中错误使用var造成undefined