• 分块【模板】


      分块板子(们):

      区间修改,区间求和:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 50005
    #define mod c+1 
    #define int long long
    int where[maxn],l[maxn],r[maxn],a[maxn],lazy[maxn],sum[maxn];
    int n,c;
    void update(int L,int R,int w)
    {
        int lnum=where[L],rnum=where[R];
        if(lnum == rnum)
        {
            for(int i = L;i <= R;i++)
                a[i] += w;
            sum[lnum] += w * (R - L + 1);
            return;
        }
        for(int i=L;i<=r[lnum];i++)    a[i]+=w;
        for(int i=l[rnum];i<=R;i++) a[i]+=w;
        sum[lnum]+=w*(r[lnum]-L+1);
        sum[rnum]+=w*(R-l[rnum]+1);
        for(int i=lnum+1;i<=rnum-1;i++) lazy[i]+=w; 
    }
    int query(int L,int R)
    {
        int ans=0;
        int lnum=where[L],rnum=where[R];
        if(lnum == rnum)
        {
            for(int i = L;i <= R;i++) (ans += a[i] + lazy[lnum]) %= mod;
            return ans;
        }
        for(int i=L;i<=r[lnum];i++)    (ans+=a[i])%=mod;
        for(int i=l[rnum];i<=R;i++) (ans+=a[i])%=mod;
        (ans+=(r[lnum]-L+1)*lazy[lnum]+(R-l[rnum]+1)*lazy[rnum])%=mod;
        for(int i=lnum+1;i<=rnum-1;i++)
        (ans+=sum[i]+lazy[i]*(r[i]-l[i]+1))%=mod; 
        return ans;
    }
    main()
    {
        scanf("%lld",&n);
        int tot=0,num=1;
        for(int i=1;i<=n;i++)
        {
            ++tot;
            if(tot>(int)sqrt(n)) { num++,tot=1; }
            if(tot==1) l[num]=i;
            if(tot==(int)sqrt(n)||i==n) r[num]=i;
            scanf("%lld",&a[i]);
            where[i]=num;
            sum[num]+=a[i];
        }
        for(int i=1;i<=n;i++)
        {
            int op,L,R;
            scanf("%lld%lld%lld%lld",&op,&L,&R,&c);
            if(op==0) update(L,R,c);
            else printf("%lld
    ",query(L,R) % mod);
        }  
        return 0;
    }

       

      区间开方,区间求和:

    #include<cstdio>
    #include<iostream>
    #include<cstring> 
    #include<algorithm>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define maxn 100005
    #define int long long
    int a[maxn],Max[maxn],where[maxn],l[maxn],r[maxn],sum[maxn];
    bool finish[maxn];
    int n,m;
    void update(int L,int R)
    {
        int lnum=where[L],rnum=where[R];
        if(lnum==rnum)
        {
            if(finish[lnum]) return ;
            int M=0,all=0;
            for(int i=L;i<=R;i++)
            {
                a[i]=(int)sqrt(a[i]);
                M=max(M,a[i]);
                all+=a[i];
            }
            for(int i=l[lnum];i<=L-1;i++) { M=max(M,a[i]),all+=a[i];};
            for(int j=R+1;j<=r[lnum];j++) { M=max(M,a[j]),all+=a[j];};
            if(M==1||M==0) finish[lnum]=1;
            sum[lnum]=all;
            return ;
        }
        for(int i=lnum+1;i<=rnum-1;i++)
        {
            if(finish[i]) continue;
            int M=0,all=0;
            for(int j=l[i];j<=r[i];j++)
            {
                a[j]=(int)sqrt(a[j]);
                M=max(M,a[j]);
                all+=a[j];
            }
            if(M==1||M==0) finish[i]=1;
            sum[i]=all;
        }
        int M=0,all=0;
        if(!finish[lnum])
        {
            for(int i=l[lnum];i<=r[lnum];i++)
            {
                if(i>=L) a[i]=(int)sqrt(a[i]);
                M=max(M,a[i]);
                all+=a[i];
            }    
            sum[lnum]=all;
            if(M==0||M==1) finish[lnum]=1;
        }
        if(!finish[rnum])
        {
            M=0,all=0;
            for(int i=l[rnum];i<=r[rnum];i++)
            {
                if(i<=R) a[i]=(int)sqrt(a[i]);
                M=max(M,a[i]);
                all+=a[i];
            }
            sum[rnum]=all;
            if(M==0||M==1) finish[rnum]=1;
        }    
    } 
    int query(int L,int R)
    {
        int lnum=where[L],rnum=where[R],M=0;
        if(lnum==rnum)
        {
            if(L==l[lnum]&&R==r[lnum]) return sum[lnum];
            for(int i=L;i<=R;i++) M+=a[i];
            return M;
        }
        for(int i=lnum+1;i<=rnum-1;i++) M+=sum[i];
        for(int i=L;i<=r[lnum];i++) M+=a[i];
        for(int i=l[rnum];i<=R;i++) M+=a[i];
        return M; 
    }
    main()
    {
        scanf("%lld",&n);
        int tot=0,num=1; 
        for(int i=1;i<=n;i++)
        {
            tot++;
            if(tot>(int)sqrt(n)) { tot=1;num++;}
            if(tot==1) l[num]=i;
            if(tot==(int)sqrt(n)||i==n) r[num]=i;
            scanf("%lld",&a[i]);
            where[i]=num;
            sum[num]+=a[i];
        }
        scanf("%lld",&m);
        for(int i=1;i<=m;i++)
        {
            int op,L,R;
            scanf("%lld%lld%lld",&op,&L,&R);
            if(op==0) update(min(L,R),max(L,R));
            else printf("%lld
    ",query(min(L,R),max(L,R)));
        }
        return 0;
    }         

       

      区间插入,单点询问:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 100005
    vector<int> q[maxn];
    int nxt[maxn];
    int n,all=1;
    void rebuild(int num)
    {
        int last=nxt[num];
        nxt[num]=++all;
        int sz=q[num].size();
        int s=sz/2;
        for(int i=0;i<sz-s;i++)
            q[all].push_back(q[num][i+s]);
        nxt[all] = last;
        q[num].erase(q[num].begin()+s,q[num].begin()+sz);
    }
    void update(int L,int d)
    {
        int sum=0,num=0;
        int i=0;
        while(1)
        {
            if(sum+q[i].size()>=L) { num=i; break; }
            sum+=q[i].size();
            i=nxt[i];
        }
        int p=L-sum;
        q[num].insert(q[num].begin()+p-1,d);
        if(q[num].size()>=2*(int)sqrt(n)) rebuild(num);
    }
    int query(int R)
    {    
        int sum=0,num=0;
        int i=0;
        while(1)
        {
            if(sum+q[i].size()>=R) { num=i; break; }
            sum+=q[i].size();
            i=nxt[i];
        }
        return q[num][R-sum-1];
    }
    int main()
    {
        scanf("%d",&n);
        int tot=0;
        for(int i=1;i<=n;i++)
        {
            tot++;
            if(tot>(int)sqrt(n)) { tot=1;nxt[all]=all+1;all++; }
            int x;
            scanf("%d",&x);
            q[all].push_back(x);
        }
        nxt[0]=1; 
        for(int i=1;i<=n;i++)
        {
            int op,L,R,c;
            scanf("%d%d%d%d",&op,&L,&R,&c);
            if(op==0) update(L,R); 
            else printf("%d
    ",query(R));
        }
        return 0;
    }
  • 相关阅读:
    P2422 良好的感觉
    拉格朗日插值
    C# 中的委托和事件(详解)
    异步委托
    ManualResetEvent详解
    快速理解C#高级概念事件与委托的区别
    拉格朗日多项式
    oracle 插入一个从别处查询获得字段的值
    decode和nvl的用法
    C#将像素值转换为图片
  • 原文地址:https://www.cnblogs.com/popo-black-cat/p/10373614.html
Copyright © 2020-2023  润新知