zoukankan      html  css  js  c++  java
  • 【csp模拟赛2】黑莲花--数据结构+数论

    没有什么能够阻挡,你对被阿的向往。天天 AK 的生涯,你的心了无牵挂。 虐过大佬的比赛,也曾装弱装逼。当你低头的瞬间,才发现旁边的人。 把你的四肢抬起来,使劲地往门上撞。盛开着永不凋零,黑莲花。 ——cx & cyx《黑莲花》

      这是一道数论题。

      

    T3

    请此题爆零的同学写一份心得体会,明天交给我。

    对于区间修改,将原数组差分之后使用树状数组即可。

    首先要知道扩展欧拉定理:对于任意的正整数a和p,且b≥φ(p)有:

     

    展欧拉定理的一个重要应用就是降幂

    而对于询问区间[l,r] mod p(其询问结果记作s(l,r,p)),可以推出:

    (假设上式中出现的模p意义下的幂指数都大于等于φ(p)

    将p不断地变成φ(p)需要O(log p)次之后p变成1

    而指数为1可以直接计算。

    所以询问s(l,r,p)可以递归做:

    1)如果l=r或者p=1则直接反回a[l]

    2)否则递归到s(l+1,r,φ(p)),记其为t。如果t≥φ(p)则返回

    ,否则反回

    剩下一个问题:如何判断指数是否大于等于φ(p)

    注意到

    所以,我们只需要取出[l+1,r]的前5个数(如果[l+1,r]的区间长度不足5则取区间[l+1,r]内所有数,如果[l+1,r]内第一个1出现的位置为x则取[l+1,x-1]内所有数)

    如果取出的数的个数为5则一定大于φ(p)。否则可以大力快速幂判断指数是否大于等于φ(p)

     

    可以用线性的欧拉筛预处理欧拉函数。

    复杂度

    实测:开O2优化并且使用普通读入优化:5.8s;使用fread3.4s

    良心搬题人为了防止卡常,开到了9s

    这是一道数据结构与数论结合的好题。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #define int long long
    const int N = 20001000;
    using namespace std;
    inline int read()
    {
    	int x = 0 , f = 1;	char ch = getchar();
    	while(ch < '0' || ch > '9')	{if(ch == '-')	f = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
    	return x * f;
    }
    int phi[N],ans,a[N],cnt,prime[N];
    int n,m,opt,l,r,p;
    bool vis[N],flag;
    void yilin()
    {
    	phi[1]=1;
    	vis[1] = 1;
    	for(int i=2;i<=20000000;i++)
    	{
    		if(!vis[i])prime[++cnt]=i , phi[i] = i - 1;
    		for(int j=1;j<=cnt && i * prime[j] <= 20000000;j++)
    		{
    			vis[i*prime[j]]=1;
    			if(i%prime[j]==0)
    			{
    				phi[i*prime[j]]=phi[i] * prime[j];
    				break;
    			}
    			phi[i*prime[j]]=phi[i] * (prime[j]-1);
    		}
    	}
    }
    //////////////////////用线段树处理区间加,单点查询
    int tr[N<<1],lazy[N<<1];
    void build(int k,int l,int r)
    {
    	if(l==r)
    	{
    		tr[k]=a[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    }
    void pushdown(int k,int l,int r)
    {
    	tr[k<<1] = tr[k<<1]+lazy[k];
    	tr[k<<1|1] = tr[k<<1|1]+lazy[k];
    	lazy[k<<1] = lazy[k];
    	lazy[k<<1|1] = lazy[k];
    	lazy[k] = 0;
    }
    void change(int k,int l,int r,int x,int y,int val)
    {
    	if(x<=l && y>=r)
    	{
    		lazy[k]+=val;
    		tr[k]+=(r-l+1)*val;
    		return ;
    	}
    	if(lazy[k]) pushdown(k,l,r);
    	int mid=(l+r) >> 1;
    	if(x<=mid)change(k<<1,l,mid,x,y,val);
    	if(y>mid)change(k<<1|1,mid+1,r,x,y,val);
    }
    int ask(int k,int l,int r,int x,int y)
    {
    	if(l>=x&&r<=y){return tr[k];}
    	if(lazy[k]) pushdown(k,l,r);
    	int mid=(l+r) >> 1;
    	if(x<=mid) return ask(k<<1,l,mid,x,y);
    	if(y>mid) return ask(k<<1|1,mid+1,r,x,y);
    }
    /////////////////////////
    c
    b
    a int ksm(int x,int y,int p)////快速幂 { int res=1; if(x >= p) flag=1,x%=p;相当于b 如果b 比p大,那么b的某一次方一定也比p大,这样才符合公式 for(;y;y>>=1) { if(y&1)res=res*x; if(res >= p) flag = true, res %= p;////快速幂,如果当前处理的值比p大,记录一下,之后才能取模,如果直接模,一直会比p小 x=(x * x); if(x >= p) flag = true, x %= p; } return res;////不及取模,影响后面对于和p 的判断 } int solve (int l,int r,int p) { // printf("%lld ",ask(1,1,n,l,l)); if(l == r) return ask(1,1,n,l,l); if(p == 1) return ask(1,1,n,l,l); int t=solve(l+1,r,phi[p]); if(t > phi[p] || flag) t = t % phi[p] +phi[p] , flag=false; int ans = ksm( ask(1,1,n,l,l) , t , p); return ans; } signed main() { #ifdef yilnr #else freopen("zzq.in","r",stdin); freopen("zzq.out","w",stdout); #endif n=read(); m=read(); for(int i=1;i<=n;i++)a[i]=read(); build(1,1,n); yilin();////线性筛欧拉函数 for(int i=1;i<=m;i++) { opt=read();l=read();r=read();p=read(); if(opt==1) { change(1,1,n,l,r,p); } if(opt==2) { flag=false;////对于每次操作,要先把flag 赋值为0 ,因为此次操作与之前无关,需重新判断; printf("%lld ",solve(l,r,p)%p ); } } fclose(stdin);fclose(stdout); return 0; }

      

  • 相关阅读:
    PostgreSQL 匹配字符串前缀
    Postgresql流复制+pgpool实现高可用
    PostgreSQL 使用Docker搭建流复制测试环境
    PostgreSQL 基于Docker的多实例安装
    PostgreSQL 基于日志的备份与还原
    PostgreSQL 利用pg_upgrade升级版本
    PostgreSQL 安装
    简单推荐系统的SQL实现
    读书笔记:集体智慧编程(1)
    Linux 光速入门
  • 原文地址:https://www.cnblogs.com/yelir/p/11536257.html
Copyright © 2011-2022 走看看