1. 程式人生 > >[BZOJ2130][均攤複雜度線段樹]魔塔

[BZOJ2130][均攤複雜度線段樹]魔塔

%%%Hillan

具體題解可以去看Claris的部落格
暴力線段樹複雜度攤一攤就nlogn了

#include <cstdio>
#include <algorithm>
#include <iostream>
#define N 100010

using namespace std;

int t,n,r;
int A[N],B[N],C[N],K[N],K1[N],f[N],ca[N],cb[N],cc[N],kb[N],kc[N],pb[N],pc[N];
struct seg{
  int l,r,Maxc,Minc,Max,flg,Maxb;
  bool
used; }T[N<<2]; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline void reaD(int &x){ char c=nc(); x=0; for(;c>'9'||c<'0';c=nc()); for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc()); } inline
void Update(int g){ int ls=g<<1,rs=g<<1|1; T[g].Maxb=max(T[ls].used?T[ls].Maxb:-1,T[rs].used?T[rs].Maxb:-1); T[g].Maxc=T[ls].used?T[ls].Maxc:T[rs].Maxc; T[g].Minc=T[rs].used?T[rs].Minc:T[ls].Minc; T[g].Max=max(T[ls].used?T[ls].Max:-1,T[rs].used?T[rs].Max:-1); T[g].used=T[ls].used|T[rs].used; } void
Build(int g,int l,int r){ T[g].l=l; T[g].r=r; T[g].flg=-1; T[g].used=1; int mid=l+r>>1; if(l==r) T[g].Maxc=T[g].Minc=f[l],T[g].Max=f[l]+pb[l],T[g].Maxb=pb[l]; else Build(g<<1,l,mid),Build(g<<1|1,mid+1,r),Update(g); } inline void toMin(int g,int x){ if(!T[g].used) return ; T[g].Maxc=T[g].Minc=x; T[g].Max=T[g].Maxb+T[g].Maxc; T[g].flg=x; } void Pushdown(int g){ if(!T[g].used) return ; if(~T[g].flg) toMin(g<<1,T[g].flg),toMin(g<<1|1,T[g].flg),T[g].flg=-1; } void Erase(int g,int l,int r){ if(!T[g].used) return ; if(T[g].l==l&&T[g].r==r) return (void)(T[g].used=0); Pushdown(g); int mid=T[g].l+T[g].r>>1; if(r<=mid) Erase(g<<1,l,r); else if(l>mid) Erase(g<<1|1,l,r); else Erase(g<<1,l,mid),Erase(g<<1|1,mid+1,r); Update(g); } void Min(int g,int l,int r,int x){ if(T[g].used==0||T[g].Maxc<=x) return ; if(T[g].l==l&&T[g].r==r&&T[g].Minc>=x) return toMin(g,x); Pushdown(g); int mid=T[g].l+T[g].r>>1; if(r<=mid) Min(g<<1,l,r,x); else if(l>mid) Min(g<<1|1,l,r,x); else Min(g<<1,l,mid,x),Min(g<<1|1,mid+1,r,x); Update(g); } int main(){ freopen("Mota.in","r",stdin); freopen("Mota.out","w",stdout); reaD(t); while(t--){ reaD(n); int ret=0,Ans=0,pre=0; for(int i=1;i<=n;i++) reaD(K[i]),K1[i]=K[i]; for(int i=1;i<=n;i++) reaD(A[i]); for(int i=1;i<=n;i++) reaD(B[i]),kb[B[i]]=i; for(int i=1;i<=n;i++) reaD(C[i]),kc[C[i]]=i; for(int i=1;i<=n;i++) reaD(ca[i]); for(int i=1;i<=n;i++) reaD(cb[i]),pb[i]=pb[i-1]+cb[i]; for(int i=1;i<=n;i++) reaD(cc[i]),ret+=cc[i],pc[i]=pc[i-1]+cc[i]; f[0]=ret; for(int i=1,j=n;i<=n;i++){ K1[B[i]]--; if(!K1[B[i]]) j=min(j,kc[B[i]]-1); f[i]=pc[j]; } Build(1,0,n); Ans=T[1].Max; for(int i=1;i<=n;i++){ K[A[i]]--; pre+=ca[i]; if(!K[A[i]]) Erase(1,kb[A[i]],n),Min(1,0,kb[A[i]]-1,pc[kc[A[i]]-1]); else Min(1,kb[A[i]],n,pc[kc[A[i]]-1]); Ans=max(Ans,pre+T[1].Max); } printf("%d\n",Ans); } }

相關推薦

[BZOJ2130][複雜線段]

%%%Hillan 具體題解可以去看Claris的部落格 暴力線段樹複雜度攤一攤就nlogn了 #include <cstdio> #include <algorithm> #include <iostream> #de

[線段 複雜] BZOJ 2130

#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; inline char nc(){ static char bu

[複雜線段]Codeforces 438D. The Child and Sequence

首先一個數模一個小於它的數,肯定會變成原來的一半 那麼用均攤複雜度線段樹的套路,記一下區間最大值,區間取模時,如果區間最大值小於模數,那麼不會改變數列,直接退出,否則暴力遞迴。 每個點最多變化log次,複雜度應該就是 O(nlog2n) #include

[複雜線段] Codeforces #438D. The Child and Sequence

水~~~ #include<cstdio> #include<algorithm> using namespace std; const int maxn=200005; typedef unsigned long long uL

玩轉資料結構——複雜和防止複雜的震盪(筆記)

資料規模 時間複雜度 並不是所有的雙層迴圈都是O(n^2)的 複雜度實驗來確定複雜度 // O(N) 兩倍增加 int findMax( int arr[], int n ){ assert( n > 0

玩轉演算法面試-資料規模,時間複雜複雜(筆記)

資料規模 時間複雜度 並不是所有的雙層迴圈都是O(n^2)的 複雜度實驗來確定複雜度 // O(N) 兩倍增加 int findMax( int arr[], int n ){ assert(

hdu 4006 The kth great number 很複雜線段,至少對於我來說,但也學會了很多!!!!!!!!!!

這道題是網路預選賽上做的,當時就是超時,後來知道是線段樹,從時間複雜度來說用線段樹先是將所用的點記錄然後nlog的快排,之後查詢就是logn了,軟和不用線段樹,之後的查詢是On的複雜度,要是來一堆大資料那就必然超時了 廢話不多說了,先將記錄的所用點排序,在離散化,建樹,將資

第二週專案3複雜體驗 漢諾

<pre class="cpp" name="code">01./* 02.*Copyright (c)2015,煙臺大學計算機與控制工程學院 03.*All rights reserved. 04.*檔名稱:漢諾塔.cbp 05.*作 者:李涵睿

HDU 6315 Naive Operations(線段+複雜

發現每次區間加只能加1,最多全域性加\(n\)次,這樣的話,最後的答案是調和級數為\(nlogn\),我們每當答案加1的時候就單點加,最多加\(nlogn\)次,複雜度可以得當保證。 然後問題就是怎麼判斷答案是否該加1。我們可以用線段樹設初值為給出的排列,把區間加改成區間減,維護最小值。當最小值為0是遍歷左右

cf250D. The Child and Sequence(線段 復雜)

etc class chm har test 一個 deb 區間 如果 題意 題目鏈接 單點修改,區間mod,區間和 Sol 如果x > mod ,那麽 x % mod < x / 2 證明: 即得易見平凡, 仿照上例顯然, 留作習題答案略, 讀者自證不難。

算法系列-複雜分析:淺析最好、最壞、平均、時間複雜

整理自極客時間-資料結構與演算法之美。原文內容更完整具體,且有音訊。購買地址: 上一節,我們講了複雜度的大 O 表示法和幾個分析技巧,還舉了一些常見覆雜度分析的例子,比如 O(1)、O(logn)、O(n)、O(nlogn) 複雜度分析。掌握了這些內容,對於複雜度分析這個知識點,你已經

最好,最壞,平均,時間複雜

// n 表示陣列 array 的長度int find(int[] array, int n, int x) {  int i = 0;  int pos = -1;  for (; i < n; ++i) {    if (array[i]

Chapter4 複雜分析(下):淺析最好,最壞,平均,時間複雜

四個複雜度分析: 1:最好情況時間複雜度(best case time complexity) 2:最壞情況時間複雜度(worst case time complexity) 3:平均情況時間複雜度(average case time complexity) 4:均攤時間複雜度(amortized t

時間複雜複雜震盪

前言 我們平常分析複雜度一般是分析一個演算法從頭執行到尾它的複雜度是怎樣的。但我們在專案中經常會寫一個複雜度較高的演算法,但是這個高複雜度的演算法是為了方便其他操作。此時我們通常會將這個複雜度較高的演算法和其他的操作放在一起來分析複雜度。這個複雜度較高的演算法複雜度將會均攤到其他的操作中

線段合併複雜證明

前言 近期對線段樹合併有了更深的瞭解,所以在這裡寫一下一些自己的想法 適用問題 線段樹合併有一類經典的模板,現在對於一棵有n個葉子節點的樹(Tip:對於一棵N個節點的樹,其葉子節點數量小於等於 ⌈

【資料結構與演算法-java實現】二 複雜分析(下):最好、最壞、平均、時間複雜的概念

上一篇文章學習了:如何分析、統計演算法的執行效率和資源消耗? 點選連結檢視上一篇文章:複雜度分析上 今天的文章學習以下內容: 最好情況時間複雜度 最壞情況時間複雜度 平均情況時間複雜度 均攤時間複雜度 1、最好與最壞情況時間複雜度 我們首先

04-演算法複雜分析(下):最好、最壞、平均、時間複雜

上一節,我們講了複雜度的大 O 表示法和幾個分析技巧,還舉了一些常見覆雜度分析的例子,比如 O(1)、O(logn)、O(n)、O(nlogn) 複雜度分析。掌握了這些內容,對於複雜度分析這個知識點,你已經可以到及格線了。但是,我想你肯定不會滿足於此。 今天我會

[BZOJ]5312: 冒險 線段 複雜分析

Description Kaiser終於成為冒險協會的一員,這次冒險協會派他去冒險,他來到一處古墓,卻被大門上的守護神擋住了去路,守護神給出了一個問題, 只有答對了問題才能進入,守護神給出了一個自然數序列a,每次有一下三種操作。 1,給出l,r,x,將序列l,r之間的所有數都 and

3L-最好、最壞、平均、時間複雜

> 關注公眾號 MageByte,設定星標點「在看」是我們創造好文的動力。後臺回覆 “加群” 進入技術交流群獲更多技術成長。 本文來自 MageByte-青葉編寫 上次我們說過 [時間複雜度與空間復度](https://mp.weixin.qq.com/s/2yDJjVJC4N404g7ISmvAzw

5312: 冒險 線段 復雜分析

ext pla .com 國際 same png 卡常 .... BE 國際慣例的題面:一看到這種維護序列的題,數據範圍分塊過不去,顯然線段樹了。考慮位運算的性質,and相當於欽定一些位必須是0,or相當於欽定一些位必須是1,這都是一些區間賦值操作。然而我們不可以按位確定,