CodeForces 1316F。大隊強[ツリーライン]

ポータル

問題の意味

列の数に\(P_1、P_2、...、P_N \) および変更するには、それぞれの変更が必要とした後、答え:
元単調に形成された列数の順位非減少\(A_1、A_2、...、 A_N \) 計算
\ [\ FRAC {\ sum_ { {iは時間\ a_j 1} ^ {N-1} \ sum_ {J = + 1} ^ {n}はa_iを\回= 2 ^ {N + IJ-1}} } ^ N-2 \]

問題の解決策

\(\ sum_は、{I 1 =回2 ^ {N + IJ-1} \ a_j sum_ {J = + 1} ^ {n}はa_iを\回\ ^ {N-1}} \) セグメントツリーであってもよいです計算。
セット管理の間隔\([L、R] \ ) ノードである(I \)\、提供:
\(ヴァル[I] \)複数の列\(a_l、A_ {L + 1}、...、A_R \)の合計値
\(SUML [I] + = A_L A_ {L} +。1つの\ 2 + ... + A_Rタイムズ\ RLタイムズ2 ^ {} \)である
\(SumR [I]は= A_L \ ^ 2回R1は。A_ {} + {L} + 1 \タイムズ^ {2} 1-RL)は、+ ... + \ A_Rある
(\ SIZ [I] \)\(a_l、A_ {L + 1}、... A_R \)の非零要素の数は、
配置(LS \)\\(I \)左の子\(RS \)\(I \)右息子、次いで:
\(ヴァル[I] =ヴァル[LS] \タイムズ2 ^ {SIZ [RS]} + SUML [LS] \タイムズSumR [RS] +ヴァル[RS] \タイムズ2 ^ {SIZ [LS]} \)
\(SUML [I] = SUML [ LS] + suml [RS] \回2 ^ {SIZ [LS]} \)
\(sumr [I] = sumr
[LS] \回2 ^ {SIZ [RS]} + sumr [RS] \) このセグメントツリーメンテナンス、我々は、任意のノードへの変更、および根を容易に行うことができるヴァル(\ \ )答えです。
この質問は、オリジナルを作るために、列の数を計算する前に、トラブルの少しですが、それは、列のと障害の切除後の番号と思われます。
実際には、列の数を増加して、セグメントツリーの維持を保証するように、初期値が最初であってもよく、すべての変更は、各操作は、ツリー行のノードに対応し、ソーティング次いで抑え、かつれます。
あなたが位置の値を変更したい場合は、最初の位置、元のツリー改行の数に対応することができます\(0 \) および現在位置の値に対応する番号を変更します。

コード

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define ff first
#define ss second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=3e5+10;
const int mod=1e9+7;
int n,q,idx[N],pos[N*2],now[N*2];
PII p[2*N];
LL po[2*N];

LL qpow(LL x,LL k){
    LL res=1;
    while(k){
        if(k&1) res=res*x%mod;
        k>>=1;x=x*x%mod;
    }
    return res;
}

struct SegTree{
    #define mid ((l+r)>>1)
    LL val[N*8],suml[N*8],sumr[N*8],siz[N*8];
    void upd(int id,int l,int r,int pos,int x){
        if(l==r) {val[id]=0;suml[id]=sumr[id]=x;siz[id]=(bool)x;return;}
        if(pos<=mid) upd(id<<1,l,mid,pos,x);
        else upd(id<<1|1,mid+1,r,pos,x);
        val[id]=(val[id<<1]*po[siz[id<<1|1]]%mod+suml[id<<1]*sumr[id<<1|1]+val[id<<1|1]*po[siz[id<<1]]%mod)%mod;
        suml[id]=(suml[id<<1]+suml[id<<1|1]*po[siz[id<<1]])%mod;
        sumr[id]=(sumr[id<<1]*po[siz[id<<1|1]]+sumr[id<<1|1])%mod;
        siz[id]=siz[id<<1]+siz[id<<1|1];
    }
    #undef mid
}tr;

int main(){
    scanf("%d",&n);
    po[0]=1;
    for(int i=1;i<=n;i++) po[i]=po[i-1]*2%mod;
    for(int i=1;i<=n;i++) scanf("%lld",&p[i].ff),p[i].ss=i;
    scanf("%d",&q);
    for(int i=1;i<=q;i++) scanf("%d%d",&idx[i],&p[i+n].ff),p[i+n].ss=i+n;
    sort(p+1,p+n+q+1);
    for(int i=1;i<=n+q;i++) pos[p[i].ss]=i;
    LL inv=qpow(po[n],mod-2);
    for(int i=1;i<=n+q;i++) if(p[i].ss<=n) {
        now[p[i].ss]=pos[p[i].ss];
        tr.upd(1,1,n+q,i,p[i].ff);
    }
    printf("%lld\n",tr.val[1]*inv%mod);
    for(int i=1;i<=q;i++){
        tr.upd(1,1,n+q,now[idx[i]],0);
        tr.upd(1,1,n+q,pos[n+i],p[pos[n+i]].ff);
        now[idx[i]]=pos[n+i];
        printf("%lld\n",tr.val[1]*inv%mod);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/BakaCirno/p/12424307.html