6398. [10.30] NOIP2018シミュレートジェネレータ(フェンウィックツリー変形部)

タイトル説明

説明

入力

出力
出力線Qは、i行目のデータDIの回答を表します。

サンプル入力
4 3 2
1 2 4
2 1 2
1 1 3 5
2 2 3

サンプル出力
0
4
14
22

データ制約

問題の解決策

明らかにCDQ +ツリーライン、プラスは、各操作の寄与を計算します

尋問は変更に依存した後に問い合わせが依存する前に、変更が行われ

しかし、セグメントツリーはフェンウィックツリーとどのような違いT、そうなります

さらにS2秒で、でフェンウィック木、取調べ1のように表さ〜T S1 + S2 *トン、保存S1(T-1)中のt修正* sのTオープンつ

コード

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define low(x) (x&-(x))
using namespace std;

struct type{
    int type,l,r,s,t,id;
} a[200001];
long long ans[200001];
long long tr[200001];
long long Tr[200001]; //*t
bool bz[200001];
int d[200001];
int n,Q,i,j,k,l,t,len;

bool cmp(type a,type b)
{
    return a.t<b.t;
}
bool Cmp(type a,type b)
{
    return a.id<b.id;
}

void Change(int t,int s)
{
    long long S=(long long)(t-1)*s;
    
    while (t<=n)
    {
        tr[t]-=S;
        Tr[t]+=s;
        
        if (!bz[t])
        bz[t]=1,d[++len]=t;
        
        t+=low(t);
    }
}
void change(int l,int r,int s)
{
    Change(l,s);
    Change(r+1,-s);
}

long long Find(int t)
{
    long long T=t,ans=0,s=0;
    
    while (t)
    {
        ans+=tr[t];
        s+=Tr[t];
        
        t-=low(t);
    }
    
    return ans+s*T;
}
long long find(int l,int r)
{
    return Find(r)-Find(l-1);
}

void clear()
{
    int i;
    
    fo(i,1,len)
    tr[d[i]]=0,Tr[d[i]]=0,bz[d[i]]=0;
    
    len=0;
}

void work(int L,int R)
{
    int i,Mid=(L+R)/2;
    
    if (L==R) return;
    
    work(L,Mid);
    work(Mid+1,R);
    
    sort(a+L,a+R+1,Cmp);
    
    fo(i,L,R)
    if (a[i].t<=Mid && a[i].type==1)
    change(a[i].l,a[i].r,a[i].s);
    else
    if (a[i].t>Mid && a[i].type==2)
    ans[a[i].t]+=find(a[i].l,a[i].r);
    
    clear();
    
    fd(i,R,L)
    if (a[i].t<=Mid && a[i].type==2)
    change(a[i].l,a[i].r,1);
    else
    if (a[i].t>Mid && a[i].type==1)
    ans[a[i].t]+=find(a[i].l,a[i].r)*a[i].s;
    
    clear();
}

int main()
{
    freopen("generator.in","r",stdin);
    freopen("generator.out","w",stdout);
    
    scanf("%d%d",&n,&Q);
    fo(i,1,Q-1)
    {
        scanf("%d",&j);
        a[j].t=i;
    }
    fo(i,1,Q)
    {
        scanf("%d",&a[i].type);
        
        if (a[i].type==1)
        scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].s);
        else
        scanf("%d%d",&a[i].l,&a[i].r);
        
        a[i].id=i;
        ++a[i].t;
    }
    
    sort(a+1,a+Q+1,cmp);
    work(1,Q);
    
    fo(i,1,Q)
    {
        ans[i]+=ans[i-1];
        printf("%lld\n",ans[i]);
    }
    
    fclose(stdin);
    fclose(stdout);
    
    return 0;
}

おすすめ

転載: www.cnblogs.com/gmh77/p/11789671.html