• 筱玛爱线段树 (树状数组)


    https://ac.nowcoder.com/acm/contest/946/

    对操作顺序执行的话,会出现递归调用的情况,这样的话复杂度起码是m^2了,所以考虑把操作离线,然后逆序执行,这样的话已经执行过的就不会再执行了,然后利用数状数组维护每个操作执行的总次数的差分数组,这样的话每执行到一个操作的时候后面的操作调用该操作的次数就可以求出来了,相当于是把每个操作的总次数先算出来,然后再执行。

    千万要注意: (A-B)%MOD这样写不行,因为会有负数情况,要+个MOD再% ,  (A-B+MOD)%MOD,对所有有%的数都要这样处理。

    #include<bits/stdc++.h>
    using namespace std;
    #define ls rt<<1
    #define rs (rt<<1)+1
    #define ll long long
    #define fuck(x) cout<<#x<<"     "<<x<<endl;
    typedef pair<int,int> pii;
    const int maxn=1e5+10;
    const int mod=1e9+7;
    int d[4][2]={1,0,-1,0,0,1,0,-1};
    ll c[maxn],bit[maxn];
    int n,m;;
    struct node
    {
        int opt,l,r;
    }op[maxn];
    int lowbit(int x){return x&-x;}
    ll query(int x)
    {
        ll ans=0;
        while(x>=1)
            ans+=bit[x],ans%=mod,x-=lowbit(x);
        return ans;
    }
    void add(int x,ll v)
    {
        while(x<=m)
            bit[x]=(bit[x]+v+mod)%mod,x+=lowbit(x);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++) scanf("%d%d%d",&op[i].opt,&op[i].l,&op[i].r);
        for(int i=m;i>=1;i--)
        {
            ll tmp=(1LL+query(i))%mod;
            if(op[i].opt==1)
                c[op[i].l]=(c[op[i].l]+tmp)%mod,c[op[i].r+1]=(c[op[i].r+1]-tmp+mod)%mod;
            else
                add(op[i].l,tmp),add(op[i].r+1,-tmp);
        }
        for(int i=1;i<=n;i++){
            c[i]=(c[i]%mod+c[i-1]%mod)%mod;
            printf("%lld ",c[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    Android测试AsyncTask下载图片
    Android DatePickerDialog TimepickerDialog
    Android AlertDialog
    Android activity的回传数据
    Android Handler简单使用
    Java Switch(String)
    JAVA测试装饰者模式
    Java实现数组按数值大小排序
    Java参数按值传递?按引用传递
    Spring cloud之断路器hystrix包问题
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754736.html
Copyright © 2020-2023  润新知