zoukankan      html  css  js  c++  java
  • 树状数组+欧拉降幂



    题目描述

    给一个长为n的序列,m次操作,每次操作:
    1.区间[l,r][l,r][l,r]加xxx
    2.对于区间[l,r][l,r][l,r],查询a[l]a[l+1]a[l+2]......a[l]^{a[l+1]^{a[l+2]......}}a[l]a[l+1]a[l+2]......modmodmoppp,一直到aaa-rrr
    请注意每次的模数不同。

    输入描述:

    第一行两个整数 n,m 表示序列长度和操作数

    接下来一行,n个整数,表示这个序列

    接下来m行,可能是以下两种操作之一:

    操作1:区间[l,r]加上 x

    操作2:查询区间[l,r]的那个式子mod p的值

    输出描述:

    对于每个询问,输出一个数表示答案
    示例1

    输入

    复制
    6 4
    1 2 3 4 5 6
    2 1 2 10000007
    2 2 3 5
    1 1 4 1
    2 2 4 10

    输出

    复制
    1
    3
    1

    备注:

    n , m <= 500000

    序列中每个数在 [1,2e9] 内,x <= 2e9 , p <= 2e7

    #include<bits/stdc++.h>
    #include<tr1/unordered_map>
    typedef long long ll;
    using namespace std;
    const int maxn=2e7+9;
    const int MAX=1e5+9; 
    bool vis[maxn];
    int cnt,prim[maxn],phi[maxn],n;
    ll a[maxn];
    typedef pair<ll,int>P;
    
    inline int lowbit(int x)
    {
    	return x&(-x);
    }
    
    inline void update(int l,int k)
    {
    	while(l<=n)
    	{
    		a[l]+=k;
    		l+=lowbit(l);
    	}
    }
    
    inline ll query(int l)
    {
    	ll ans=0;
    	while(l)
    	{
    		ans+=a[l];
    		l-=lowbit(l);
    	}
    	return ans;
    }
    
    inline ll read()
    {
    	ll res=0;
    	char c=getchar();
    	while(!isdigit(c))c=getchar();
    	while(isdigit(c))res=(res<<1)+(res<<3)+c-48,c=getchar();
    	return res;
    }
    
    inline void init()
    {
    	ll i,j;
    	vis[1]=phi[1]=1;
    	for(i=2;i<=maxn-9;i++)
    	{
    		if(!vis[i])
    		{
    			prim[++cnt]=i;
    			phi[i]=i-1;
    		}
    		for(j=1;j<=cnt&&i*prim[j]<=maxn-9;++j)
    		{
    			vis[i*prim[j]]=1;
    			if(i%prim[j]==0)
    			{
    				phi[i*prim[j]]=phi[i]*prim[j];break;
    			}
    			phi[i*prim[j]]=phi[i]*(prim[j]-1);
    		}
    	}
    }
    
    P Pow(ll a,ll b,ll p)
    {
    	ll ans=1,temp=1,i;
    	int flag=0;
    	for(i=1;i<=b;i++)
    	{
    		temp=temp*a;
    		if(temp>=p)
    		{
    			flag=1;break;
    		}
    	}
    	a%=p;
    	while(b)
    	{
    		if(b&1)ans=ans*a%p;
    		a=a*a%p;
    		b>>=1;
    	}
    	return P(ans,flag);
    }
    
    inline P getans(ll l,ll r,ll p)
    {
    	ll a=query(l);
    	if(a==1||l==r||p==1)return P(a%p,a>=p?1:0);
    	P b=getans(l+1,r,phi[p]);
    	if(b.second)b.first+=phi[p];
    	return Pow(a,b.first,p);
    }
    
    int main()
    {
    	int m,i;
    	scanf("%d%d",&n,&m);
    	init();
    	for(i=1;i<=n;i++)
    	{
    		ll a;
    		scanf("%lld",&a);
    		update(i,a);
    		update(i+1,-a);
    	}
    	while(m--)
    	{
    		int opt;
    		ll l,r,x;
    		scanf("%d%lld%lld%lld",&opt,&l,&r,&x);
    		if(opt==1)
    		{
    			update(l,x);
    			update(r+1,-x);
    		}
    		else
    		{
    			printf("%lld
    ",getans(l,r,x).first);
    		}
    	}
    }
    

    链接:https://ac.nowcoder.com/acm/problem/17190
    来源:牛客网

    欢迎加我qq1165750856一起玩呀~
  • 相关阅读:
    35个Java代码优化的细节,你知道几个?
    Java如何优雅地实现接口数据校验
    Java中方法的重载详解(含系统配套视频)
    七大经典、常用排序算法的原理、Java 实现以及算法分析
    Java静态方法和实例方法
    Java静态变量和实例变量
    “反转链表”相关的题目
    【C++】将十进制数转换为十六进制数
    第四章:动态规划I
    【C++】数组中的第k个最小元素
  • 原文地址:https://www.cnblogs.com/HHHEN/p/11782694.html
Copyright © 2011-2022 走看看