1. 程式人生 > >寫過的部分板子

寫過的部分板子

退役之前把自己敲過的板子都發一下,不會有詳細的解釋,只能保證碼風適合大部分人的閱讀習慣

 

你將會在這篇文章中看到這些模板:

 

·快讀

·最短路——dijkstra及spfa

·最小生成樹

·LCA的tarjan演算法

·強連通分量的tarjan演算法以及割點的tarjan演算法

·最小樹形圖,朱劉演算法

·最大流,dinic

·差分約束

·乘法逆元線性篩

·Lucas定理

·FFT

·洲閣篩篩素數個數

·樹狀陣列及線段樹

·treap和splay

·樹鏈剖分

·KMP和manacher

 

好的,那麼開始吧

 

inline int read(){
  int k=0,f=1; char c=getchar();
  while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
  while(c<='9'&&c>='0'){k=k*10+c-'0';c=getchar();}
  return k*f;
}
快讀

 

#include <stdio.h>
#include <algorithm>
#include <queue>
using
namespace std; typedef pair<int,int> pr;//dist,num struct edges { int to,val; }; int n,m,s; int dis[10010]; vector<edges> e[10010]; void dijkstra() { priority_queue<pr,vector<pr>,greater<pr> > q; q.push(pr(0,s)); while(!q.empty()) { pr temp=q.top(); q.pop();
int nm=temp.second; if(dis[nm]<temp.first) continue; for(int i=0;i<e[nm].size();i++) { if(dis[e[nm][i].to]>dis[nm]+e[nm][i].val) { dis[e[nm][i].to]=dis[nm]+e[nm][i].val; q.push(pr(dis[e[nm][i].to],e[nm][i].to)); } } } for(int i=1;i<=n;i++)printf("%d ",dis[i]); } int main() { for(int i=0;i<=10005;i++) dis[i]=2147483647; int x,y,z; scanf("%d %d %d",&n,&m,&s); dis[s]=0; for(int i=1;i<=m;i++) { scanf("%d %d %d",&x,&y,&z); e[x].push_back({y,z}); } dijkstra(); return 0; }
dijkstra,luogu p3371
#include <stdio.h>
#include <algorithm>
#include <deque>
#include <vector>
#include <string.h>
#define INF 1000000007
using namespace std;
struct node
{
    int to,val;
}u;
deque<int> deq;
int work(int n,int m)
{
    deq.clear();
    vector<node> poi[120];
    int dis[120];
    bool visit[120];
    int x,y,v;
    int now;
    int k;
    memset(visit,false,sizeof(visit));
    fill(dis,dis+111,INF);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&x,&y,&v);
        u.val=v;
        u.to=y;
        poi[x].push_back(u);
        u.to=x;
        poi[y].push_back(u);
    }
    visit[1]=true;
    dis[1]=0;
    deq.push_back(1);
    while(!deq.empty())
    {
        now=deq.front();
        deq.pop_front();
        visit[now]=false;
        for(int i=0;i<poi[now].size();i++)
        {
            if(dis[poi[now][i].to]>dis[now]+poi[now][i].val)
            {
                dis[poi[now][i].to]=dis[now]+poi[now][i].val;
                if(!visit[poi[now][i].to])
                {
                    visit[poi[now][i].to]=true;
                    if(deq.empty()) deq.push_front(poi[now][i].to);
                    else
                    {
                        k=deq.front();
                        if(dis[poi[now][i].to]<dis[k]) deq.push_front(poi[now][i].to);
                        else deq.push_back(poi[now][i].to);
                    }
                      
                }
            }
        }
    }
    return dis[n];
}
int main()
{
    int n,m;
    while(1)
    {
        scanf("%d %d",&n,&m);
        if(n==0&&m==0) return 0;
        else
        {
            printf("%d\n",work(n,m));
        }
    }
    return 0;
}
spfa,hdu2544

 

#include <stdio.h>
#include <algorithm>
using namespace std;
struct Edges
{
    int a,b;
    long long len;
}e[200100];
int n,m;
int f[50020];
 
inline bool cmp(struct Edges a,struct Edges b)
{return a.len<b.len;}
 
inline int findf(int a)
{
    if(f[a]==a) return a;
    else
    {
        f[a]=findf(f[a]);
        return f[a];
    }
}
inline void merge(int a,int b)
{
    int x=findf(a),y=findf(b);
    f[x]=y;
}
 
int main()
{
    int ej=0;
    long long ans=0;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        f[i]=i;
    }
    int x,y;
    long long l;
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %lld",&e[i].a,&e[i].b,&e[i].len);
    }
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=m;i++)
    {
        if(findf(e[i].a)!=findf(e[i].b))
        {
            ej++;
            ans+=e[i].len;
            merge(e[i].a,e[i].b);
        }
    }
    if(ej<n-1)
    {
        printf("orz");
        return 0;
    }
    printf("%lld",ans);
    return 0;
}
最小生成樹kruskal,luogu p3366

 

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
struct questions
{
    int next,sum,ans,num;
}q[1000005];
int qans[500100];
struct edges
{
    int to,next;
}e[1000005];
bool visit[500100],vis[500100];
int treef[500100],uff[500100],anc[500100];
int heade[500100],headq[500100];
int n,m,s;
int sume,sumq;
 
inline int read()
{
    int f=1,k=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){k=k*10+c-'0';c=getchar();}
    return k*f;
}
int buf[10];
inline int write(int i)
{
    int p=0;
    if(i==0) p++;
    else while(i)
    {
        buf[p++]=i%10;
        i/=10;
    }
    for(int j=p-1;j>=0;j--) putchar('0'+buf[j]);
}
 
 
inline int findf(int a)
{
    if(uff[a]==a) return a;
    else
    {
        uff[a]=findf(uff[a]);
        return uff[a];
    }
}
inline void merge(int a,int b)
{
    int x=findf(a),y=findf(b);
    uff[x]=y;
}
 
inline void LCA(int now)
{
    visit[now]=true;
    for(int i=heade[now];i;i=e[i].next)
    {
        if(!visit[e[i].to])
        {
            LCA(e[i].to);
            merge(now,e[i].to);
            //printf("%d %d\n",now,e[i].to);
        }
        anc[findf(now)]=now;
    }
    vis[now]=true;
    //printf("now=%d findf(now)=%d\n",now,findf(now));
    //for(int i=1;i<=n;i++) printf("%d ",uff[i]);
    //for(int i=1;i<=n;i++) printf("%d ",anc[i]);
    //printf("\n");
    for(int i=headq[now];i;i=q[i].next)
    {
        int x=q[i].sum;
        //printf(" %d %d\n",now,x);
        if(vis[x])
        {
            q[i].ans=anc[findf(x)];
            //printf("now=%d findfnow=%d ans=%d num=%d\n",now,findf(now),q[i].ans,q[i].num);
            qans[q[i].num]=q[i].ans;
        }
    }
}
 
int main()
{
    int x,y;
    n=read();m=read();s=read();
    for(int i=1;i<=n-1;i++)
    {
        x=read();y=read();
        e[++sume].to=y;
        e[sume].next=heade[x];
        heade[x]=sume;
        e[++sume].to=x;
        e[sume].next=heade[y];
        heade[y]=sume;
    }
    for(int i=1;i<=m;i++)
    {
        x=read();y=read();
        q[++sumq].next=headq[x];
        q[sumq].sum=y;
        q[sumq].num=i;
        headq[x]=sumq;
        q[++sumq].next=headq[y];
        q[sumq].sum=x;
        q[sumq].num=i;
        headq[y]=sumq;
    }
    for(int i=1;i<=n;i++)
    {
        uff[i]=i;
        anc[i]=0;
    }
    LCA(s);
    for(int i=1;i<=m;i++)
    {
        write(qans[i]);
        printf("\n");
    }
    return 0;
}
LCA tarjan,luogu p3379

 

#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
#include <stack>
using namespace std;
 
vector<int> edges[5050];
set<int> se[5050];
stack<int> st;
int dfn[5050],lowlink[5050];
int dfsno,seno,n,m;
bool instk[5050];
 
void DFS(int now)
{
    dfn[now]=lowlink[now]=++dfsno;
    st.push(now);
    instk[now]=true;
    for(int i=0;i<edges[now].size();i++)
    {
        int t=edges[now][i];
        if(!dfn[t])
        {
            DFS(t);
            lowlink[now]=min(lowlink[now],lowlink[t]);
        }
        else if(instk[t]) lowlink[now]=min(lowlink[now],dfn[t]);
    }
    if(lowlink[now]==dfn[now])
    {
        seno++;
        while(1)
        {
            int p=st.top();
            st.pop();
            instk[p]=false;
            se[seno].insert(p);
            if(p==now) break;
        }
    }
}
 
int main()
{
    int x,y,op;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&x,&y,&op);
        if(op==1) edges[x].push_back(y);
        else if(op==2)
        {
            edges[x].push_back(y);
            edges[y].push_back(x);
        }
    }
     
    for(int i=1;i<=n;i++)
    {
        if(!dfn[i]) DFS(i);
    }
     
    int ans=1;
    for(int i=2;i<=seno;i++)
    {
        if(se[i].size()>se[ans].size()||(se[i].size()==se[ans].size()&&*(se[i].begin())>*(se[ans].begin()))) ans=i;
    }
    printf("%d\n",se[ans].size());
    for(set<int>::iterator it=se[ans].begin();it!=se[ans].end();it++)
    {
        printf("%d ",*it);
    }
    return 0;
}
強聯通分量tarjan,luogu p1726
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
 
struct izayoi
{
    int to,next;
}e[200200];
int head[100100],num;
 
int dfn[100100],lowlink[100100];
int n,m,cnt;
 
bool cut[100100];
bool flag[100100];
 
void add(int from,int to)
{
    e[++num].to=to;
    e[num].next=head[from];
    head[from]=num;
}
 
void DFS(int now)
{
    dfn[now]=lowlink[now]=++cnt;
    int child=0;
    for(int i=head[now];i;i=e[i].next)
    {
        if(!dfn[e[i].to])
        {
            DFS(e[i].to);
            lowlink[now]=min(lowlink[now],lowlink[e[i].to]);
            if(lowlink[e[i].to]>=dfn[now]&&(!flag[now])) cut[now]=true;
            if(flag[now]) child++;
        }
        lowlink[now]=min(lowlink[now],dfn[e[i].to]);
    }
    if(flag[now]&&child>=2) cut[now]=true;
}
int main()
{
    //freopen("p3388.in","r",stdin);
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;i++)
    {
        if(!dfn[i]) flag[i]=true,DFS(i);
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(cut[i]) ans++;
    }
    printf("%d\n",ans);
    for(int i=1;i<=n;i++)
    {
        if(cut[i])printf("%d ",i);
    }
    return 0;
}
割點tarjan,luogu p3388

 

#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
const int INF=1000000009;
inline int read()
{
    int k=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c<='9'&&c>='0'){k=k*10+c-'0';c=getchar();}
    return k*f;
}
 
int n,m,root;
struct izyoi
{
    int x,y;
    int val;
}e[10010];
int pre[110],id[110];
int visit[110];
int in[110];
 
int Zhu_Liu(int root)
{
    int ans=0,cnt=0;
    while(1)
    {
        cnt=0;
        memset(id,0,sizeof(id));
        memset(visit,0,sizeof(visit));
        fill(in+1,in+n+1,INF);
        for(int i=1;i<=m;i++)
        {
            int x=e[i].x,y=e[i].y;
            if(in[y]>e[i].val&&x!=y) pre[y]=x,in[y]=e[i].val;
        }
        in[root]=0;
        for(int i=1;i<=n;i++) if(in[i]==INF) return -1;
        for(int i=1;i<=n;i++)
        {
            ans+=in[i];
            int v=i;
            while(visit[v]!=i&&!id[v]&&v!=root)
            {
                visit[v]=i;
                v=pre[v];
            }
            if(v!=root&&!id[v])
            {
                id[v]=++cnt;
                for(int u=pre[v];u!=v;u=pre[u]) id[u]=cnt;
            }
        }
        if(!cnt) break;
        for(int i=1;i<=n;i++) if(!id[i]) id[i]=++cnt;
        for(int i=1;i<=m;i++)
        {
            int x=e[i].x,y=e[i].y;
            e[i].x=id[x];e[i].y=id[y];
            if(id[x]!=id[y]) e[i].val-=in[y];
        }
        n=cnt;
        root=id[root];
    }
    return ans;
}
int main()
{
    n=read();m=read();root=read();
    int x,y,z;
    for(int i=1;i<=m;i++)
    {
        x=read();y=read();z=read();
        if(x!=y)
        {
            e[i].x=x;
            e[i].y=y;
            e[i].val=z;
        }
        else
        {
            i--;m--;
        }
    }
    printf("%d",Zhu_Liu(root));
    return 0;
}
最小樹形圖 朱劉演算法,luogu p4716

 

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <string.h>
#include <iostream>
#define INF 1000000007
using namespace std;
typedef long long llw;
inline int read()
{
    llw k=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){k=k*10+c-'0';c=getchar();}
    return k*f;
}
long long n,m,s,t;
struct edges
{
    llw from,to,cap,flow;
};
vector<edges> eds;
vector<llw> gra[1001000];
bool visit[1001000];
llw dis[1001000];
llw cur[1001000];
bool BFS()
{
    memset(visit,false,sizeof(visit));
    queue<llw> que;
    llw x;
    que.push(s);
    dis[s]=0;
    visit[s]=true;
    while(!que.empty())
    {
        x=que.front();
        que.pop();
        for(llw i=0;i<gra[x].size();i++)
        {
            edges& e=eds[gra[x][i]];
            if(!visit[e.to]&&e.cap>e.flow)
            {
                visit[e.to]=true;
                dis[e.to]=dis[x]+1;
                que.push(e.to);
            }
        }
    }
    return visit[t];
}
llw DFS(llw now,llw a)
{
    //printf("%d\n",now);
    if(now==t||a==0) return a;
    long long flow=0,f;
    //printf("%lld\n",now);
    for(llw &i=cur[now];i<gra[now].size();i++)
    {
        edges& e=eds[gra[now][i]];
        if(dis[now]+1==dis[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
        {
            e.flow+=f;
            eds[gra[now][i]^1].flow-=f;
            flow+=f;
            a-=f;
            if(a==0) break;
        }
    }
    return flow;
}
int main()
{
    //freopen("p3376.in","r",stdin);
    int x,y,z;
    n=read();m=read();s=read();t=read();
    //printf("%lld %lld %lld %lld\n",n,m,s,t);
    for(int i=0;i<m;i++)
    {
        //printf("%d\n",i);
        x=read();y=read();z=read();
        eds.push_back((edges){x,y,z,0});
        eds.push_back((edges){y,x,0,0});
        int k=eds.size();
        gra[x].push_back(k-2);
        gra[y].push_back(k-1);
        //printf("%d\n",k);
    }
    int flow=0;
    while(BFS())
    {
        memset(cur,0,sizeof(cur));
        flow+=DFS(s,INF);
    }
    cout<<flow;
    return 0;
}
網路最大流dinic,loj101

 

#include <stdio.h>
#include <algorithm>
using namespace std;
const int INF=100000007;
 
struct izyoi
{
    int to,val,next;
}edges[250000];
int num;
int head[50000];
inline void add(int x,int y,int val)
{
    edges[++num].to=y;
    edges[num].val=val;
    edges[num].next=head[x];
    head[x]=num;
}
 
int dis[50000];
bool visit[50000];
 
int n,m;
 
bool spfa(int now)
{
    visit[now]=true;
    for(int i=head[now];i;i=edges[i].next)
    {
        if(dis[edges[i].to]<dis[now]+edges[i].val)
        {
            dis[edges[i].to]=dis[now]+edges[i].val;
            if(visit[edges[i].to]) return false;
            if(!spfa(edges[i].to)) return false;
        }
    }
    visit[now]=false;
    return true;
}
int main()
{
    scanf("%d %d",&n,&m);
    int opt,a,b,c;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&opt);
        if(opt==3)
        {
            scanf("%d %d",&a,&b);
            add(a,b,0);
            add(b,a,0);
        }
        else if(opt==1)
        {
            scanf("%d %d %d",&a,&b,&c);
            add(b,a,c);
        }
        else
        {
            scanf("%d %d %d",&a,&b,&c);
            add(a,b,-c);
        }
    }
    fill(dis+1,dis+22000,-INF);
    for(int i=1;i<=n;i++) add(0,i,0);
    if(!spfa(0)) printf("No");
    else printf("Yes");
    return 0;
}
差分約束,luogu p1993

 

#include <stdio.h>
#include <algorithm>
using namespace std;
long long inv[7000000];
long long p,n;
int main()
{
    scanf("%lld %lld",&n,&p);
    inv[1]=1;
    for(int i=2;i<=n;i++)
    {
        inv[i]=(p-p/i)*inv[p%i]%p;
    }
    for(int i=1;i<=n;i++)
    {
        printf("%lld\n",inv[i]);
    }
    return 0;
}
乘法逆元線性篩,loj110

 

#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long llw;
 
llw fac[100100];
llw n,m,p;
 
llw fp(llw a,llw x,llw mod)
{
    llw ans=1;
    while(x>0)
    {
        if(x&1) ans*=a;
        a*=a;
        x>>=1;
        ans%=mod;a%=mod;
    }
    return ans;
}
 
llw C(llw n,llw m,llw p)
{
    if(m>n) return 0;
    return (fac[n]*fp((fac[m]*fac[n-m])%p,p-2,p))%p;
}
llw Lucas(llw n,llw m,llw p)
{
    if(n<p&&m<p) return C(n,m,p);
    return (Lucas(n/p,m/p,p)*C(n%p,m%p,p))%p;
}
int main()
{
    freopen("p3807.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld %lld %lld",&n,&m,&p);
        fac[0]=1;
        for(int i=1;i<=p;i++) fac[i]=fac[i-1]*i%p;
        printf("%lld\n",Lucas(n+m,m,p));
    }
    return 0;
}
Lucas定理,luogu p3807

 

#include <stdio.h>
#include <algorithm>
#include <complex>
#include <cmath>
#include <cstdlib>
using namespace std;
 
inline int read()
{
    int k=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c<='9'&&c>='0'){k=(k<<1)+(k<<3)+c-'0';c=getchar();}
    return k*f;
}
const double PI=acos(-1);
 
complex<double> omega[3000000],omegaInverse[3000000];
complex<double> c1[3000000],c2[3000000];
int n,m;
int a1[1000010],a2[1000010];
 
void transform(complex<double> *a,int n,complex<double> *omega)
{
    int k=0;
    while((1<<k)<n) k++;
    for(int i=0;i<n;i++)
    {
        int t=0;
        for(int j=0;j<k;j++) if(i&(1<<j)) t|=(1<<(k-j-1));
        if(i<t) swap(a[i],a[t]);
    }
     
    for(int l=2;l<=n;l<<=1)
    {
        int m=l/2;
        for(complex<double> *p=a;p!=a+n;p+=l)
        {
            for(int i=0;i<m;i++)
            {
                complex<double> t=omega[n/l*i]*p[m+i];
                p[i+m]=p[i]-t;
                p[i]+=t;
            }
        }
    }
     
}
int main()
{
    n=read();m=read();
    int t;
    for(int i=0;i<=n;i++) a1[i]=read(),c1[i].real(a1[i]);
    for(int i=0;i<=m;i++) a2[i]=read(),c2[i].real(a2[i]);
    if(n==0) 
    {
        for(int i=0;i<=m;i++) printf("%d ",a1[0]*a2[i]);
        return 0;
    }
    else if(m==0)
    {
        for(int i=0;i<=n;i++) printf("%d ",a2[0]*a1[i]);
        return 0;
    }
     
    for(t=1;t<m+n;t<<=1);
    for(int i=0;i<t;i++)
    {
        omega[i]=complex<double>(cos(2*PI/t*i),sin(2*PI/t*i));
        omegaInverse[i]=conj(omega[i]);
    }
     
    transform(c1,t,omega);transform(c2,t,omega);
    for(int i=0;i<t;i++) c1[i]*=c2[i];
     
    transform(c1,t,omegaInverse);
    for(int i=0;i<t;i++) c1[i]/=t;
     
    for(int i=0;i<=n+m;i++) printf("%d ",(int)floor(c1[i].real()+0.5));
    return 0;
}
FFT,luogu p3803

 

#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
 
typedef long long llw;
llw p[500000],pre[500000],tot;
bool visit[500000];
llw num,last[2000000];
llw g[2000000],val[2000000];
 
void pr(llw m)
{
    memset(p,0,sizeof(p));
    memset(pre,0,sizeof(pre));
    memset(visit,false,sizeof(visit));
    for(llw i=2;i<=m;i++)
    {
        pre[i]=pre[i-1];
        if(!visit[i])
        {
            p[++tot]=i;pre[i]++;
        }
        for(llw j=1;j<=tot&&(llw)i*p[j]<=m;j++)
        {
            visit[i*p[j]]=true;
        }
    }
}
 
llw cal(llw m)
{
    if(m<=0)return 0;
    memset(last,0,sizeof(last));
    num=0;
 
    llw hlf=(llw)sqrt(m);
    llw fles=upper_bound(p+1,p+tot+1,hlf)-p-1;
    for(llw i=m;i>=1;i=m/(m/i+1)) val[++num]=m/i;
    for(llw i=1;i<=num;i++) g[i]=val[i];
    for(llw i=1;i<=fles;i++)
    {
        for(llw j=num;j>=1;j--)
        {
            llw k=val[j]/p[i];if(k<p[i]) break;
            k=k<hlf?k:num-m/k+1;
            g[j]-=g[k]-(i-last[k]-1);
            last[j]=i;
        }
    }
    return pre[hlf]+g[num]-1;
}
int main()
{
    llw n;
    scanf("%lld",&n);
    pr((llw)sqrt(n)+1);
    printf("%lld\n",cal(n));
    return 0;
}
洲閣篩篩素數個數 luogu p6235

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lowbit(i) ((i)&(-i))
int f[102000],ans[52000],t=0;
int n,m;
void update(int x,int v)
{
    for(int i=x;i<=n;i+=lowbit(i))
    {
        f[i]+=v;
    }
}
int getnum(int x)
{
    int sum=0;
    for(int i=x;i>0;i-=lowbit(i))
    {
        sum+=f[i];
    }
    return sum;
}
int main()
{
    memset(f,0,sizeof(f));
    int i,x,a,b,c;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&x);
        update(i,x);
    }
    //for(i=1;i<=n;i++)printf(" %d ",f[i]);
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d %d %d",&a,&b,&c);
        if(a==1)
        {
            update(b,c);
        }
        else ans[++t]=getnum(c)-getnum(b-1);
    }
    for(i=1;i<=t;i++)printf("%d\n",ans[i]);
    return 0;
}
樹狀陣列_1,codevs1080
#include <stdio.h>
#define lowbit(i) ((i)&(-i))
int p[100005],n,m,ans[100010],t=0;
void update(int x,int v)
{
    for(int i=x;i>0;i-=lowbit(i))
    {
        p[i]+=v;
    }
}
int getsum(int x)
{
    int s=0;
    for(int i=x;i<=n;i+=lowbit(i))
    {
        s+=p[i];
    }
    return s;
}
int main()
{
    int i,x,a,b,c,d;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&x);
        update(i,x);
        update(i-1,-x);
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d",&a);
        if(a==1)
        {
            scanf("%d %d %d",&b,&c,&d);
            update(c,d);
            update(b-1,-d);
        }
        else
        {
            scanf("%d",&b);
            ans[++t]=getsum(b);
        }
    }
    for(i=1;i<=t;i++)printf("%d\n",ans[i]);
    return 0;
}
樹狀陣列_2,codevs1081

 

#include <stdio.h>
#include <algorithm>
using namespace std;
long long t[666666];
long long lazy[666666];
long long s[666666];
void build(int now,int l,int r)
{
    lazy[now]=0;
    if(l==r) s[now]=t[l];
    else
    {
        int mid=(l+r)/2;
        int lchild=now<<1;
        int rchild=lchild|1;
        build(lchild,l,mid);
        build(rchild,mid+1,r);
        s[now]=s[lchild]+s[rchild];
    }
}
void PushDown(int now,int l,int r,int mid,int lchild,int rchild)
{
    //int lchild=now<<1;
    //int rchild=lchild|1;
    //int mid=(l+r)/2;
    lazy[lchild]+=lazy[now];
    lazy[rchild]+=lazy[now];
    s[lchild]+=(mid-l+1)*lazy[now];
    s[rchild]+=(r-mid)*lazy[now];
    lazy[now]=0;
}
void Upd(int now,int l,int r,int lrequest,int rrequest,int k)
{
    if(l>=lrequest&&r<=rrequest)
    {
        s[now]+=k*(r-l+1);
        lazy[now]+=k;
        return;
    }
    else
    {
        int mid=(l+r)/2;
        int lchild=now<<1;
        int rchild=lchild|1;
        if(lazy[now]!=0) PushDown(now,l,r,mid,lchild,rchild);
        if(lrequest<=mid) Upd(lchild,l,mid,lrequest,rrequest,k);
        if(rrequest>mid) Upd(rchild,mid+1,r,lrequest,rrequest,k);
        s[now]=s[lchild]+s[rchild];
    }
}
long long Query(int now,int l,int r,int lrequest,int rrequest)
{
    if(l>=lrequest&&r<=rrequest) return s[now];
    else
    {
        int mid=(l+r)/2;
        int lchild=now<<1;
        int rchild=lchild|1;
        long long ans=0;
        if(lazy[now]!=0) PushDown(now,l,r,mid,lchild,rchild);
        if(lrequest<=mid) ans+=Query(lchild,l,mid,lrequest,rrequest);
        if(rrequest>mid) ans+=Query(rchild,mid+1,r,lrequest,rrequest);
        return ans;
    }
}
int main()
{
    int n,m,x,l,r;
    long long k;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&t[i]);
    }
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&x);
        if(x==1)
        {
            scanf("%d %d %lld",&l,&r,&k);
            //printf("\n");
            //for(int i=1;i<=2*n-1;i++) printf("%lld ",s[i]);
            //printf("\n");
            Upd(1,1,n,l,r,k);
        }
        else
        {
            scanf("%d %d",&l,&r);
            printf("%lld\n",Query(1,1,n,l,r));
        }
    }
    return 0;
}
線段樹,luogu p3372

 

#include <stdio.h>
#include <algorithm>
using namespace std;
int ch[100100][2],v[100100],rd[100100],cnt[100100],sze[100100],id;
int root;
 
#define lc ch[now][0]
#define rc ch[now][1]
 
void update(int now)
{
    sze[now]=sze[lc]+sze[rc]+cnt[now];
}
void rotate(int &now,int d)
{
    int v=ch[now][d^1];
    ch[now][d^1]=ch[v][d];
    ch[v][d]=now;
    update(now);
    update(now=v);
}
void insert(int &now,int val)
{
    if(!now)
    {
        now=++id;
        lc=rc=0;
        v[now]=val;
        rd[now]=rand();
        sze[now]=cnt[now]=1;
        return;
    }
    if(val==v[now])
    {
        cnt[now]++;sze[now]++;
        return;
    }
    int d=(v[now]<val);
    insert(ch[now][d],val);
    sze[now]++;
    if(rd[now]>rd[ch[now][d]])rotate(now,d^1);
}
bool remove(int &now,int val)
{
    if(!now) return false;
    if(v[now]==val)
    {
        if(cnt[now]>1)
        {
            sze[now]--;cnt[now]--;
            return true;
        }
        if(!lc||!rc)
        {
            now=lc?lc:rc;
            return true;
        }
        if(rd[lc]>rd[rc]) rotate(now,0);
        else rotate(now,1);
        return remove(now,val);
    }
    int d=(v[now]<val);
    if(!remove(ch[now][d],val)) return false;
    sze[now]--;
    return true;
}
int find_rnk(int val)
{
    int now=root,rnk=1;
    while(now)
    {
        if(val<v[now]) now=lc;
        else if(val>v[now])
        {
            rnk+=sze[lc]+cnt[now];
            now=rc;
        }
        else return rnk+sze[lc];
    }
    return 0;
}
int find_val(int rnk)
{
    int now=root;
    while(now)
    {
        if(rnk<=sze[lc]) now=lc;
        else if(rnk>sze[lc]+cnt[now])
        {
            rnk-=(sze[lc]+cnt[now]);
            now=rc;
        }
        else return v[now];
    }
    return 0;
}
int find_pre(int val)
{
    int now=root,pre;
    while(now)
    {
        if(v[now]<val)
        {
            pre=v[now];
            now=rc;
        }
        else now=lc;
    }
    return pre;
}
int find_nxt(int val)
{
    int now=root,nxt;
    while(now)
    {
        if(v[now]>val)
        {