題目:click
題意:
題意簡單,題目毒瘤,我真的吐了,寫的線段樹最後一個點瘋狂T,改爲樹狀數組的區間更新,單點查詢(有不懂的可以參考:click)。加歐拉降冪,有些細節要對a進行處理。其他的見代碼。但是別人的線段樹沒有T。。。。。也給出代碼,大佬指點一下線段樹怎麼改。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 500005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
long double eps=1e-9;
ll phi[20000005];
ll primes[20000005],pcnt=0;
bool vis[20000005];
inline void getPhi(int num)
{
phi[1]=1;
for(int i=2;i<=num;++i)
{
if(!vis[i])
primes[++pcnt]=i,phi[i]=i-1;
for(int j=1;j<=pcnt&&i*primes[j]<=num;++j)
{
vis[i*primes[j]]=1;
if (!(i%primes[j]))
{phi[i * primes[j]] = phi[i] * primes[j]; break;}
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
}
}
}
ll a[500010];
ll BIT[500010];
int NH;
inline ll lowbit(ll x)
{
return x&(-x);
}
void add(int pos,ll val)
{
for(;pos<=NH;pos+=lowbit(pos))
BIT[pos]+=val;
}
ll query(ll pos)
{
ll sum=0;
for(;pos;pos-=lowbit(pos))
sum+=BIT[pos];
return sum;
}
inline ll MOD(ll n,ll mod)
{
return n<mod?n:(n%mod+mod);
}
inline ll quickpow(ll a,ll n,ll mod)
{
ll res=1;
a=MOD(a,mod);//防爆long long 注意
while(n)
{
if(n&1)
res=MOD(a*res,mod);
n>>=1;
a=MOD(a*a,mod);
}
return res;
}
inline ll solve(int l,int r,ll mod)
{
ll val=query(l)+a[l];
if(l==r||mod==1)
return MOD(val,mod);
return quickpow(val,solve(l+1,r,phi[mod]),mod);
}
int main()
{
memset(BIT,0,sizeof(BIT));
getPhi(20000005);
int m;
scanf("%d %d",&NH,&m);
for(int i=1;i<=NH;i++)
{
scanf("%lld",&a[i]);
}
while(m--)
{
int op,l,r;
ll p;
scanf("%d %d %d %lld",&op,&l,&r,&p);
if(op==1)
{
add(l,p);
if(r+1<=NH)
add(r+1,-p);
}
else
{
printf("%lld\n",solve(l,r,p)%p);
}
}
return 0;
}
T的代碼:
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 500005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
long double eps=1e-9;
ll phi[20000005];
ll primes[20000005],pcnt=0;
bool vis[20000005];
void getPhi(int num)
{
phi[1]=1;
for(int i=2;i<=num;++i)
{
if(!vis[i])
primes[++pcnt]=i,phi[i]=i-1;
for(int j=1;j<=pcnt&&i*primes[j]<=num;++j)
{
vis[i*primes[j]]=1;
if (!(i%primes[j]))
{phi[i * primes[j]] = phi[i] * primes[j]; break;}
phi[i * primes[j]] = phi[i] * (primes[j] - 1);
}
}
}
struct A {
int l,r;
ll w,lazy;
}tree[MAX_len];
ll a[500010];
void build_tree(int p,int l1,int r1)
{
tree[p].l=l1,tree[p].r=r1;
tree[p].lazy=0;
if(l1==r1)
{
tree[p].w=a[l1];
return ;
}
int mid=(l1+r1)>>1;
build_tree((p<<1),l1,mid);
build_tree((p*2+1),mid+1,r1);
tree[p].w=tree[(p<<1)].w+tree[(p<<1)|1].w;
}
void PushDown(int p)
{//下放標記
if(tree[p].lazy>0)
{
ll temp=tree[p*2].r-tree[p*2].l+1;
tree[p*2].w+=tree[p].lazy*temp;
temp=tree[p*2+1].r-tree[p*2+1].l+1;
tree[p*2+1].w+=tree[p].lazy*temp;
tree[p*2].lazy+=tree[p].lazy;
tree[p*2+1].lazy+=tree[p].lazy;
tree[p].lazy=0;
}
}
void update(int p,int l1,int r1,ll val)
{
if(tree[p].l>=l1&&tree[p].r<=r1)
{
tree[p].w+=val*(tree[p].r-tree[p].l+1);
tree[p].lazy+=val;
return ;
}
PushDown(p);
int mid=(tree[p].l+tree[p].r)/2;
if(l1<=mid)
{
update(p*2,l1,r1,val);
}
if(r1>mid)
{
update(p*2+1,l1,r1,val);
}
tree[p].w=tree[p*2].w+tree[p*2+1].w;
}
ll query(int p,int l1,int r1)
{
if(tree[p].l==tree[p].r)
{
return tree[p].w;
}
PushDown(p);
int mid=(tree[p].l+tree[p].r)/2;
ll res=0;
if(l1<=mid)
{
res+=query(p*2,l1,r1);
}
if(r1>mid)
{
res+=query(p*2+1,l1,r1);
}
return res;
}
ll MOD(ll n,ll mod)
{
return n<mod?n:(n%mod+mod);
}
ll quickpow(ll a,ll n,ll mod)
{
ll res=1;
a=MOD(a,mod);//防爆long long 注意
while(n)
{
if(n&1)
res=MOD(a*res,mod);
n>>=1;
a=MOD(a*a,mod);
}
return res;
}
ll solve(int l,int r,ll mod)
{
ll val=query(1,l,l);
if(l==r||mod==1)
return MOD(val,mod);
return quickpow(val,solve(l+1,r,phi[mod]),mod);
}
int main()
{
getPhi(20000005);
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
build_tree(1,1,n);
while(m--)
{
int op,l,r;
ll p;
scanf("%d %d %d %lld",&op,&l,&r,&p);
if(op==1)
{
update(1,l,r,p);
}
else
{
ll val=query(1,l,r);
if(l==r)
{
printf("%lld\n",val%p);
continue;
}
printf("%lld\n",solve(l,r,p)%p);
}
}
return 0;
}