【BZOJ 4869】【2017六省联考】相逢是问候
来源:互联网 发布:mac删除键 编辑:程序博客网 时间:2024/05/17 06:34
考虑一个欧拉定理的扩展:
当
也叫作欧拉定理EXT,证明看这里:https://zhuanlan.zhihu.com/p/24902174
这个公式的强大之处在于a和p可以不互质,也就是说p可以不为质数。
然后证明一个结论:这个操作在操作
显然可以发现一个数
然后就可以发现在不断地套用欧拉定理的时候,指数模
考虑使用线段树来做,如果当前区间全部已经不再变化就退出,否则暴力修改下去。所以最坏情况下每个数会修改
但是在这里我们默认了修改一次的时间是
接着我们尝试优化掉一个log:计算快速幂的那个log。为什么可以优化掉呢?因为底数一定是c,而指数最大是1e8,那么我们可以预处理
#include<cmath>#include<cstdio>#include<vector>#include<queue>#include<cstring>#include<iomanip>#include<stdlib.h>#include<iostream>#include<algorithm>#define ll long long#define inf 1000000000#define N 50005#define ls x<<1#define rs x<<1|1#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;int sum[N*4],num[N*4],tag[N*4],a[N];int f[N][100],cc[N][100],ex_c[N][100],pp[100];int n,m,p,c,k,i,opt,l,r;int quick_power(int x,int a,int mo){ int res = 1; while (a) {if (a&1) res=(1ll*res*x)%mo; x=(1ll*x*x)%mo; a>>=1;} return res;}void pushup(int x) {sum[x] = (sum[ls] + sum[rs]) % p; tag[x] = tag[ls] + tag[rs];}void build(int x,int l,int r){ if (l == r) {sum[x] = a[l]; num[x] = 0; tag[x] = r - l + 1; return;} int mid = (l + r) >> 1; build(ls,l,mid); build(rs,mid+1,r); pushup(x);}void change(int x,int l,int r,int L,int R){ if (L <= l && r <= R && !tag[x]) return; if (l == r) { num[x]++; sum[x] = f[l][num[x]]; if (num[x] == k) tag[x]--; return; } int mid = (l + r) >> 1; if (L <= mid) change(ls,l,mid,L,R); if (mid < R) change(rs,mid+1,r,L,R); pushup(x);}int query(int x,int l,int r,int L,int R){ if (L <= l && r <= R) return sum[x]; int mid = (l + r) >> 1; ll res = 0; if (L <= mid) res += query(ls,l,mid,L,R); if (mid < R) res += query(rs,mid+1,r,L,R); return res % p;}int phi(int x){ int i,res = x; fo(i,2,sqrt(x)) if (!(x%i)) {while (!(x%i)) x/=i;res = res/i*(i-1);} if (x-1) res=res/x*(x-1); return res;}int q_p(int x,int a,int mm){ if (a <= 10000) return cc[a][mm]; return (1ll*ex_c[a/10000][mm]*cc[a%10000][mm])%pp[mm];}int get_(int x,int num,int d){ int t; if (!num) if (x > pp[d]) return x%pp[d]; else return x; t = get_(x,num-1,d+1); double q = log(1.0/x*pp[d+1])/log(1.0*c)-num+1; if (q<=0) t += pp[d+1]; return q_p(c,t,d);}void pre(){ int i,j; fo(i,0,10000) fo(j,0,k) { cc[i][j] = quick_power(c,i,pp[j]); int g = quick_power(c,10000,pp[j]); ex_c[i][j] = quick_power(g,i,pp[j]); } fo(i,1,n) if (a[i] == 0) { f[i][1] = 1; fo(j,2,k) f[i][j] = get_(1,j-1,0); } else { fo(j,1,k) f[i][j] = get_(a[i],j,0); } }int main(){ scanf("%d%d%d%d",&n,&m,&p,&c); k = 0; pp[0] = p; while (pp[k]-1) {k++; pp[k] = phi(pp[k-1]);} k++; pp[k] = 1; fo(i,1,n) scanf("%d",&a[i]); pre(); build(1,1,n); while (m--) { scanf("%d%d%d",&opt,&l,&r); if (opt == 0) change(1,1,n,l,r); if (opt == 1) printf("%d\n",query(1,1,n,l,r)); } //fo(i,l,r) printf("%d ",query(1,1,n,i,i)); return 0;}
- 【BZOJ 4869】【2017六省联考】相逢是问候
- [扩展欧拉定理] BZOJ 4869 [Shoi2017]相逢是问候
- bzoj 4869: [Shoi2017]相逢是问候 数论+线段树
- 4869: [Shoi2017]相逢是问候
- BZOJ 4869 [Shoi2017]相逢是问候 扩展欧拉定理+线段树
- 【BZOJ 4872】【2017六省联考】分手是祝愿
- 【BZOJ4869】【SHOI2017】相逢是问候
- 【BZOJ 4868】【2017六省联考】期末考试
- 【GDOI2018模拟7.9】相逢是问候
- 【GDOI2018模拟7.9】相逢是问候
- [题解]bzoj4869 SHOI2017相逢是问候
- 【BZOJ 4870】【2017六省联考】组合数问题
- 【BZOJ 4873】【2017六省联考】寿司餐厅
- JLOI2017——相逢是问候,离别是祝愿
- [JZOJ5214]【HEOI、SXOI2017】相逢是问候(口胡)
- 【BZOJ4869】相逢是问候(线段树+欧拉定理)
- 洛谷 P3745 [六省联考2017]期末考试(bzoj P4868 [Shoi2017]期末考试)
- [六省联考2017]组合数问题
- iOS使用TestFlight进行Beta测试
- C#操作mysql数据库的实例
- 日期控件
- 使用Apache commons-codec Base64实现加解密(转)
- Kafka+ELK集成
- 【BZOJ 4869】【2017六省联考】相逢是问候
- Eclipse导出可运行的jar包并运行
- 《JavaScript高级语言设计》(第三版)学习笔记(8)
- 1064. Complete Binary Search Tree (30)
- 史上最全的Servlet基础教程(收藏)
- 【深度剖析HMM(附Python代码)】4.HMM代码测试及hmmlearn介绍
- Android完美解决多次点击Toast一直提示不消失问题
- quartz 时间触发器-02
- 有关在thinkphp.CN中的讨论的回应