CCF(分割):修飾セグメントツリー間隔(50分)+変性セグメントツリーポイント(100)+セグメントツリー(100)

除算

201709から5

  • この質問を行うには、多くの方法が最も一般的に使用されるツリーラインとフェンウィックの木である、があります。
  • ツリーラインが何をした場合は、更新間隔変更機能を考えます。しかし、Vにそこに関連している可能性がある1または[j]は、このように時間のうち、0で、50分まで。
  • あなたはこの質問を行うには、使用のポイントを変更、コードを変更することができます。判定するための主な機能の内部に1サイクルで増加。
  • もちろん、途中フェンウィックの木があり、実行している時間以上この方法とこの方法はほぼ同じですが、コードが大幅に削減されます。
  • vはlong long型であれば、それは読むための方法のscanf関数のLLD%を使用しないように最善である、ということに注意してください、そうでない場合はタイムアウト。

コードのツリーラインを使用します。

//线段树求解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100005;
int n,m;
int a[maxn];
long long sum[maxn<<2];
void pushup(int id,int l,int r){
    int lc=id<<1;
    int rc=id<<1|1;
    sum[id]=sum[lc]+sum[rc];
}
void build(int id,int l,int r){
    if(l==r){
        sum[id]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    int lc=id<<1;
    int rc=id<<1|1;
    build(lc,l,mid);
    build(rc,mid+1,r);
    pushup(id,l,r);
}
//---------------------------区间修改
// void update(int id,int l,int r,int p,int q,int v){
//     if(l==r){
//         if(sum[id]>=v&&sum[id]%v==0)
//             sum[id]/=v;
//         return;
//     }
//     int mid=(l+r)>>1;
//     if(p<=mid){
//         update(id<<1,l,mid,p,q,v);
//     }
//     if(q>mid){
//         update(id<<1|1,mid+1,r,p,q,v);
//     }
//     pushup(id,l,r);
// }
//-------------------------------点修改
void update(int id,int l,int r,int p){
    if(l==r){
        sum[id]=a[p];
        return;
    }
    int mid=(l+r)>>1;
    if(p<=mid){
        update(id<<1,l,mid,p);
    }
    if(p>mid){
        update(id<<1|1,mid+1,r,p);
    }
    pushup(id,l,r);
}
long long query(int id,int l,int r,int p,int q){
    long long sums=0;
    if(p<=l&&q>=r){
        return sum[id];
    }
    int mid=(l+r)>>1;
    if(p<=mid){
        sums+=query(id<<1,l,mid,p,q);
    }
    if(q>mid){
        sums+=query(id<<1|1,mid+1,r,p,q);
    }
    return sums;
}
int main(){
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    scanf("%d%d",&n,&m);
    //cin>>n>>m;
    for(int i=1;i<=n;i++){
        //cin>>a[i];
        scanf("%d",&a[i]);
    }
    build(1,1,n);
    for(int i=0;i<m;i++){
        int opt,p,q;
        scanf("%d%d%d",&opt,&p,&q);
        //cin>>opt>>p>>q;
        if(opt==1){//update
            int v;
            scanf("%d",&v);
            //cout<<v<<endl;
            //cin>>v;
            //-------------------------------区间修改
            // if(v==1)
            //     continue;
            // update(1,1,n,p,q,v);
            if(v==1)
                continue;
            //     //--------------------------点修改
            for(int j=p;j<=q;j++){
                if(a[j]>=v&&a[j]%v==0){
                    a[j]/=v;
                    update(1,1,n,j);
                }
            }
        }else{
            cout<<query(1,1,n,p,q)<<endl;
        }
    }
    //system("pause");
    return 0;
}

コードを使用してフェンウィックツリー:

//树状数组求解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100005;
int n,m;
int a[maxn];
long long c[maxn];
int lowbit(int x){
    return x&(-x);
}
long long sum(int x){
    long long ret=0;
    while(x>0){
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
void add(int x,int v){
    while(x<=n){
        c[x]+=v;
        x+=lowbit(x);
    }
}
int main(){
    // ios::sync_with_stdio(false);
    // cin.tie(0);
    //cin>>n>>m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        //cin>>a[i];
        scanf("%d",&a[i]);
        add(i,a[i]);
    }
    for(int i=0;i<m;i++){
        int opt;
        //cin>>opt;
        scanf("%d",&opt);
        if(opt==1){
            int p,q;int v;
            //cin>>p>>q>>v;
            scanf("%d%d%d",&p,&q,&v);//这里不能用%lld来读取long long 型,
            if(v==1)
                continue;
            for(int j=p;j<=q;j++){
                if(a[j]>=v&&a[j]%v==0){
                    add(j,a[j]/v-a[j]);
                    a[j]/=v;
                }
            }
        }else{
            int p,q;
            //cin>>p>>q;
            scanf("%d%d",&p,&q);
            cout<<sum(q)-sum(p-1)<<endl;
        }
    }
    //system("pause");
    return 0;
}

おすすめ

転載: www.cnblogs.com/GarrettWale/p/11456868.html
おすすめ