模板库

写在前面:我是一只蒟蒻。。。

快速幂模板:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll b,p,k;
 5 int main(){
 6     scanf("%lld%lld%lld",&b,&p,&k);
 7     ll c=b,d=p;
 8     ll ans=1;
 9     while(p){
10         if(p&1){
11             ans=(ans*b)%k;
12         }
13         b=(b*b)%k;
14         p>>=1;
15     }
16 //    cout<<c<<"^"<<d<<" mod "<<k<<"="<<ans%k;
17     printf("%d
",ans%k);
18     return 0;
19 }
快速幂模板

线段树模板:

#include<bits/stdc++.h>
#define ll long long
const int N=5e6+8;
using namespace std;
ll n,m,tag[N],ans[N],a[N];
ll ls(ll x){
    return x<<1;
}//左儿子扩展 (x*2) 
ll rs(ll x){
    return x<<1|1;
}//右儿子扩展(x*2+1) 
void up(ll x){
    ans[x]=ans[ls(x)]+ans[rs(x)];
}// 求出当前点的总和值 
void build(ll l,ll r,ll p){
    if(l==r){
        ans[p]=a[l];
        return;
    }
    ll mid=(l+r)>>1;
    build(l,mid,ls(p));//左儿子建树 
    build(mid+1,r,rs(p));//右儿子建树
    up(p);//进行整合 
}
void f(ll l,ll r,ll p,ll k){//k是懒(延迟)标记的数值 
    tag[p]+=k;
    ans[p]+=(r-l+1)*k;
}//tag[]懒标记点。
void down(ll l,ll r,ll p){
    ll mid=(l+r)>>1;
    f(l,mid,ls(p),tag[p]);//左传 
    f(mid+1,r,rs(p),tag[p]);//右传 
    tag[p]=0;//懒标记传递结束,清零 
} 
void xg(ll xl,ll xr,ll l,ll r,ll p,ll k){//修改操作 
    if(l>=xl&&xr>=r){//当前区间被所查询的区间包含 
        ans[p]+=(r-l+1)*k;
        tag[p]+=k;
        return ; 
    }
    down(l,r,p);//懒坐标传递 
    ll mid=(l+r)>>1;
    if(xl<=mid){
        xg(xl,xr,l,mid,ls(p),k);    
    }
    if(xr>mid){
        xg(xl,xr,mid+1,r,rs(p),k);
    } 
    up(p);//更新该节点 
} 
ll query(ll gl,ll gr,ll l,ll r,ll p){
    ll an=0;
    if(gl<=l&&gr>=r){
        return ans[p];
    }
    ll mid=(l+r)>>1;
    down(l,r,p);
    if(gl<=mid){
        an+=query(gl,gr,l,mid,ls(p));
    }
    if(gr>mid){
        an+=query(gl,gr,mid+1,r,rs(p));
    }
    return an;
}
ll fl,x,y,z;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }        
    build(1,n,1);
    for(int i=1;i<=m;i++){
        scanf("%d",&fl);
        if(fl==1){
            scanf("%lld%lld%lld",&x,&y,&z);
            xg(x,y,1,n,1,z);    
        }
        if(fl==2){
            scanf("%lld%lld",&x,&y);
            printf("%lld
",query(x,y,1,n,1));
        }
    }
    return 0;
} 
线段树模板(区间加,区间查询)
#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int N=5e6+7;
ll ans[N],a[N],at[N],ml[N];
ll fl,n,m,P,x,y,z;
ll ls(ll x){
    return x<<1;
}
ll rs(ll x){
    return x<<1|1;
}
void up(ll p){
    ans[p]=(ans[ls(p)]+ans[rs(p)])%P;
}
void build(ll l,ll r,ll p){
    at[p]=0;
    ml[p]=1;
    if(l==r){
        ans[p]=a[l];
        return;
    }
    ll mid=(l+r)>>1;
    build(l,mid,ls(p));
    build(mid+1,r,rs(p));
    up(p);
}
void down(ll l,ll r,ll p){
    ml[ls(p)]=(ml[ls(p)]*ml[p])%P;
    ml[rs(p)]=(ml[rs(p)]*ml[p])%P;
    at[ls(p)]=(at[ls(p)]*ml[p])%P;
    at[rs(p)]=(at[rs(p)]*ml[p])%P;
    ans[ls(p)]=(ans[ls(p)]*ml[p])%P;
    ans[rs(p)]=(ans[rs(p)]*ml[p])%P;
    ml[p]=1;//乘懒标记传递完成,清零处理,乘法优先于加法,所以先计算乘法再计算加法 
    ll mid=(l+r)>>1;
    at[ls(p)]=(at[ls(p)]+at[p])%P;
    at[rs(p)]=(at[rs(p)]+at[p])%P;
    ans[ls(p)]=(ans[ls(p)]+(mid-l+1)*at[p])%P;
    ans[rs(p)]=(ans[rs(p)]+(r-mid)*at[p])%P;
    at[p]=0; 
}
void xg(ll gl,ll gr,ll l,ll r,ll p,ll k){
    if(l>=gl&&gr>=r){
        at[p]=(k+at[p])%P;
        ans[p]=((r-l+1)*k+ans[p])%P;
        return ;
    }
    down(l,r,p);
    ll mid=(l+r)>>1;
    if(gl<=mid){
        xg(gl,gr,l,mid,ls(p),k);
    }
    if(gr>mid){
        xg(gl,gr,mid+1,r,rs(p),k);
    }
    up(p);
}//修改+; 
void ch(ll cl,ll cr,ll l,ll r,ll p,ll k){
    if(l>=cl&&r<=cr){
        ml[p]=(ml[p]*k)%P;
        at[p]=(at[p]*k)%P;
        ans[p]=(ans[p]*k)%P;
        return ;
    }
    down(l,r,p);
    ll mid=(l+r)>>1;
    if(cl<=mid){
        ch(cl,cr,l,mid,ls(p),k);
    }
    if(cr>mid){
        ch(cl,cr,mid+1,r,rs(p),k);
    }
    up(p);
}//修改*; 
ll query(ll al,ll ar,ll l,ll r,ll p){
    ll an=0;
    if(al<=l&&ar>=r){
        return ans[p]%P;
    }
    down(l,r,p);
    ll mid=(l+r)>>1;
    if(al<=mid){
        an=an+query(al,ar,l,mid,ls(p));
    }
    if(ar>mid){
        an=an+query(al,ar,mid+1,r,rs(p));
    }
    return an%P;
}
int main(){
    scanf("%lld%lld%lld",&n,&m,&P);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    build(1,n,1);
    for(int i=1;i<=m;i++){
        scanf("%lld",&fl);
        if(fl==1){
            scanf("%lld%lld%lld",&x,&y,&z);
            ch(x,y,1,n,1,z);
        }
        if(fl==2){
            scanf("%lld%lld%lld",&x,&y,&z);
            xg(x,y,1,n,1,z);
        }
        if(fl==3){
            scanf("%lld%lld",&x,&y);
            printf("%lld
",(query(x,y,1,n,1))%P);
        }
    }
    
    return 0;
}
线段树模板(区间加乘,区间查询)

  

离散化处理:

 1 for(int i=1;i<=n;i++){
 2             scan(a[i].x);scan(a[i].y);scan(a[i].e);
 3             book[++tot]=a[i].x;
 4             book[++tot]=a[i].y;
 5         }
 6         sort(book,book+tot);
 7         int reu=unique(book,book+tot)-book;
 8         for(int i=1;i<=n;i++){
 9             a[i].x=lower_bound(book,book+reu,a[i].x)-book;
10             a[i].y=lower_bound(book,book+reu,a[i].y)-book;
11         }
洛谷P1955离散化处理
原文地址:https://www.cnblogs.com/xishirujin/p/10505442.html