• P3747 [六省联考 2017] 相逢是问候


    P3747 [六省联考 2017] 相逢是问候

    问候出题人母亲

    0x01 题意

    给定一个长为(n)的序列,支持两个操作((\%p)意义下):

    1. 区间修改(将该数修改为某数的该数次幂)
    2. 区间求和

    0x02 解

    看见区间求和就是线段树

    区间修改应该和数学有关

    求幂的话可以用欧拉定理

    然后这个题应该就做完了

    哦对还有预处理不然会T

    不搞了不是强迫症

    线段树维护两个参数,一个是这个区间的和,一个是这个区间里求幂次数的最小值

    当求幂次数大于(log(p))时模数就变成(1)了,就没有必要算下去了

    因此每个数都最多算(log)次,复杂度是(O(nlog^2))

    单点暴力改就行不用tag,tag还麻烦

    预处理要把每个数的幂提前算好

    用扩展欧拉定理算

    开俩数组把(c)的幂装下,这里用到压位的思想,把前四个数用一个数组表示,后四个数用一个数组表示,然后再开俩数组存它们可不可以用欧拉定理

    最后递推合并成一个算形如(c^{c^{c^{c...}}})的三维数组就行了

    具体看代码

    0x03 码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=100010;
    
    int phi[N],g[N],s1[N][30],s2[N][30];
    bool b1[N][30],b2[N][30];
    int f[N][30][30];
    bool bj[N][30][30];
    int a[N],len=0,n,m,p,c;
    
    struct node{
    	int mn,s;
    }t[N<<2];
    
    int gcd(int a,int b){
        return b?a:gcd(b,a%b);
    }
    
    int getphi(int n){
    	int ans=n,m=sqrt(n);
    	for(int i=2;i<=m;i++){
    		if(n%i==0){
    			ans=ans/i*(i-1);
    			while(n%i==0) n/=i;
    		}
    	}
    	if(n>1) ans=ans/n*(n-1);
    	return ans;
    }
    
    void pre(){
    	int x=p;
    	phi[0]=p;
    	while(x!=1) x=getphi(x),phi[++len]=x;
    	phi[++len]=1;
    	for(int i=0;i<=len;i++) g[i]=gcd(c,phi[i]);
    	for(int i=0;i<=len;i++){
    		s2[0][i]=1;
    		for(int j=1;j<=10000;j++){
    			s2[j][i]=s2[j-1][i]*c;
    			if(s2[j][i]>=phi[i]) s2[j][i]%=phi[i],b2[j][i]=1;
    			b2[j][i]|=b2[j-1][i];
    		}
    	}
    	for(int j=0;j<=len;j++){
    		s1[0][j]=1;
    		b1[1][j]=b2[10000][j];
    		for(int i=1;i<=10000;i++){
    			s1[i][j]=s1[i-1][j]*s2[10000][j];
    			if(s1[i][j]>=phi[j]) s1[i][j]%=phi[j],b1[i][j]=1;
    			b1[i][j]|=b1[i-1][j];
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int k=0;k<=len;k++){
    			f[i][0][k]=a[i]%phi[k];
    			if(a[i]>=phi[k]) bj[i][0][k]=1;
    		}
    		for(int j=1;j<=len;j++){
    			f[i][j][len]=0;
    			for(int k=0;k<len;k++){
    				f[i][j][k]=s1[f[i][j-1][k+1]/10000][k]*s2[f[i][j-1][k+1]%10000][k];
    				bj[i][j][k]=(b1[f[i][j-1][k+1]/10000][k]||b2[f[i][j-1][k+1]%10000][k]);
    				if(f[i][j][k]>=phi[k]) f[i][j][k]%=phi[k],bj[i][j][k]=1;
    				if(g[k]!=1&&bj[i][j-1][k+1]){
    					f[i][j][k]=f[i][j][k]*s1[phi[k+1]/10000][k]%phi[k]*s2[phi[k+1]%10000][k];
    					if(f[i][j][k]>=phi[k]){f[i][j][k]%=phi[k];bj[i][j][k]=1;}
    					bj[i][j][k]=(bj[i][j][k]||b1[phi[k+1]/10000][k]||b2[phi[k+1]%10000][k]);
    				}
    			}
    		}
    	}
    	return;
    }
    
    void pushup(int x){
    	t[x].mn=min(t[x<<1].mn,t[x<<1|1].mn);
    	t[x].s=t[x<<1].s+t[x<<1|1].s;
    	return;
    }
    
    void build(int x,int l,int r){
    	if(l==r){
    		t[x].s=a[l];
    		t[x].mn=0;
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(x<<1,l,mid);
    	build(x<<1|1,mid+1,r);
    	pushup(x);
    }
    
    void change(int x,int l,int r,int cl,int cr){
    	if(t[x].mn>=len) return;
    	if(l>cr||r<cl) return;
    	if(l==r){
    		t[x].mn++;
    		t[x].s=f[l][t[x].mn][0]%p;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(t[x<<1].mn<len) change(x<<1,l,mid,cl,cr);
    	if(t[x<<1|1].mn<len) change(x<<1|1,mid+1,r,cl,cr);
    	pushup(x);
    	return;
    }
    
    int query(int x,int l,int r,int ql,int qr){
    	if(l>qr||r<ql) return 0;
    	if(l>=ql&&r<=qr) return t[x].s%p;
    	int mid=(l+r)>>1;
    	return (query(x<<1,l,mid,ql,qr)+query(x<<1|1,mid+1,r,ql,qr))%p;
    }
    
    signed main(){
    	cin>>n>>m>>p>>c;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	pre(); 
    	build(1,1,n);
    	for(int i=1;i<=m;i++){
    		int op,l,r;
    		cin>>op>>l>>r;
    		if(op) printf("%lld
    ",query(1,1,n,l,r));
    		else change(1,1,n,l,r);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    使用特殊构造的5GB文件测试Win2012Dedup功能
    VMWare 回收磁盘空间
    一个极其高效的虚拟机内存冗余消除机制:UKSM
    基于Dedup的数据打包技术
    hadoop集群运行dedup实现去重功能
    Qt编写安防视频监控系统24-自定义悬浮条
    Qt编写百度地图综合应用(在线+离线+区域)
    Qt编写安防视频监控系统23-图片地图
    Qt编写安防视频监控系统22-摄像机搜索
    Qt编写安防视频监控系统21-摄像机管理
  • 原文地址:https://www.cnblogs.com/wsyunine/p/14504459.html
Copyright © 2020-2023  润新知