选拔赛之 线段树

来源:互联网 发布:白手套 知乎 编辑:程序博客网 时间:2024/05/17 22:35
id=98
这道题自己陷入了一个坑,,
用了快速乘, 就会超时,,
快速乘只是用来防止中间结果溢出的,反而会比乘法慢
顺便复习下快速乘代码,,
这个地方还有一个坑就是数论里面的东西。。现在还不知道为什么。。
有个小坑就是ak≡ak mod (p−1)(mod p)a ^ k \equiv a ^ {k\ mod \ (p - 1)} (mod\ p)akak mod (p1)(mod p),ppp是素数.

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<string>#include<cstring>#include<iomanip>#include<iostream>#include<stack>#include<cmath>#include<map>#include<vector>#define ll long long#define inf 0x3f3f3f3f#define INF 1000000000#define bug1 cout<<"bug1"<<endl;#define bug2 cout<<"bug2"<<endl;#define bug3 cout<<"bug3"<<endl;using namespace std;const int maxn=100005;const int mod=1e9+7;int a[maxn];ll sum[maxn*4],lazy[maxn*4];ll qpow(ll a,ll k){    ll ret=1;    while(k){        if(k&1){            ret=ret*a%mod;        }        a=a*a%mod;        k>>=1;    }    return ret;}void build(int rt,int l,int r){    if(l==r){sum[rt]=a[l];return;}    int mid=(l+r)>>1;    build(rt<<1,l,mid);    build(rt<<1|1,mid+1,r);    sum[rt]=sum[rt<<1]*sum[rt<<1|1]%mod;}void down(int rt){    sum[rt<<1]=qpow(sum[rt<<1],lazy[rt]);    sum[rt<<1|1]=qpow(sum[rt<<1|1],lazy[rt]);    lazy[rt<<1]=lazy[rt<<1]*lazy[rt]%(mod-1);    lazy[rt<<1|1]=lazy[rt<<1|1]*lazy[rt]%(mod-1);// 是mod   mod-1    lazy[rt]=1;}void update(int ql,int qr,int l,int r,int rt,int b){    if(ql<=l&&r<=qr){        sum[rt]=qpow(sum[rt],b);        lazy[rt]=lazy[rt]*b%(mod-1);        return;    }    if(lazy[rt]!=1)down(rt);    int mid=(l+r)>>1;    if(ql<=mid)update(ql,qr,l,mid,rt<<1,b);    if(mid<qr)update(ql,qr,mid+1,r,rt<<1|1,b);    sum[rt]=sum[rt<<1]*sum[rt<<1|1]%mod;}ll query(int ql,int qr,int l,int r,int rt){    if(ql<=l&&r<=qr){        return sum[rt];    }    if(lazy[rt]!=1)down(rt);    int mid=(l+r)>>1;    ll ret=1;    if(ql<=mid)ret=ret*query(ql,qr,l,mid,rt<<1)%mod;    if(mid<qr)ret=ret*query(ql,qr,mid+1,r,rt<<1|1)%mod;    return ret;}void init(){    for(int i=1;i<4*maxn;++i){        lazy[i]=1;        sum[i]=1;    }    memset(a,0,sizeof(a));}int main(){    int t;    scanf("%d",&t);    while(t--){        init();        int n,q;        scanf("%d%d",&n,&q);        for(int i=1;i<=n;++i){            scanf("%d",&a[i]);        }        build(1,1,n);        for(int i=1;i<=q;++i){            int op;            scanf("%d",&op);            if(op==1){                int l,r,b;                scanf("%d%d%d",&l,&r,&b);                update(l,r,1,n,1,b);            }            else{                int l,r;                scanf("%d%d",&l,&r);                cout<<query(l,r,1,n,1)<<'\n';            }        }    }}

0 0
原创粉丝点击