zoukankan      html  css  js  c++  java
  • 题解[CF906D Power Tower]

    题目描述

    长度为(n)的数组(w) ,模数(P)

    (m)次询问,每次询问求((w_l^{w_{l+1}^{w_{l+2}^{...^{w_r}}}}) \% P)

    Sol

    这是一道对欧拉定理进行简单应用的题,难度还好。

    看到次方套次方的就想到欧拉定理。具体的在这里就不说了。

    只要用一个性质:

    [a^b equiv a^b (mod P) ,b< phi(P) ① ]

    [a^b equiv a^{b \% phi(P)+phi(P)}(mod P) ,b>=phi(P)② ]

    然后我们一层一层“剥”掉次方,递归求解。

    我们来对着代码说

    快速幂

    inline ll ksm(ll a,ll b,ll M){
    	ll res=1;
    	while(b){
    		if(b&1){
    			res=res*a;
    			if(res>M) res=res%M+M;//满足②式
    		}
    		a=a*a;
    		if(a>M) a=a%M+M;//满足②式
    		b>>=1;
    	}
    	return res;
    }
    

    递归

    inline ll dfs(int id,ll M,int limit){
    	if(id==limit+1||M==1) return 1;//到达右端点或者φ变为1
      //任何数模1都为0
    	int now=dfs(id+1,phi[M],limit);//now是当前a[id]要乘的次数
    	return ksm(a[id],now,M);//M是当前的模数
    }
    

    Code

    #include<bits/stdc++.h>
    #define ll long long
    #define N (100010)
    using namespace std;
    int n,m;
    ll P,a[N];
    map<ll,int>phi;
    inline ll read(){
    	ll w=0;
    	char ch=getchar();
    	while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9'){
    		w=(w<<3)+(w<<1)+(ch^48);
    		ch=getchar();
    	}
    	return w;
    }
    inline ll Phi(ll x){
    	ll res=x;
    	for(int i=2;i*i<=x;i++){
    		if(x%i==0){
    			res=res/i*(i-1);
    			while(x%i==0) x=x/i;
    		}
    	}
    	if(x>1) res=res/x*(x-1);
    	return res;
    }
    inline ll ksm(ll a,ll b,ll M){
    	ll res=1;
    	while(b){
    		if(b&1){
    			res=res*a;
    			if(res>M) res=res%M+M;
    		}
    		a=a*a;
    		if(a>M) a=a%M+M;
    		b>>=1;
    	}
    	return res;
    }
    inline ll dfs(int id,ll M,int limit){
    	if(id==limit+1||M==1) return 1;
    	int now=dfs(id+1,phi[M],limit);
    	return ksm(a[id],now,M);
    }
    int main(){
    	n=read(),P=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	int tmp=P;
    	while(tmp!=1) phi[tmp]=Phi(tmp),tmp=phi[tmp];
    	phi[tmp]=1;
      //把可能要用的预处理出来
    	m=read();
    	for(int i=1;i<=m;i++){
    		int l=read(),r=read();
    		printf("%lld
    ",dfs(l,P,r)%P);
    	}
    	return 0;
    }
    

    完结撒花❀

  • 相关阅读:
    element-ui 中 el-table 根据scope.row行数据变化动态显示行内控件
    vue.js 父组件主动获取子组件的数据和方法、子组件主动获取父组件的数据和方法
    把json1赋值给json2,修改json2的属性,json1的属性也一起变化
    win10下当前目录右键添加CMD快捷方式
    element-ui
    vscode 头部注释插件
    IE浏览器new Date()带参返回NaN解决方法
    常用css
    使用DataGridView控件显示数据
    第四章 ADO.NET
  • 原文地址:https://www.cnblogs.com/xxbbkk/p/14466293.html
Copyright © 2011-2022 走看看