ZJOI2016 線段樹 解題報告

2021-07-22 21:42:57 字數 2884 閱讀 1499

。。很久以前看過題面然後沒有仔細想,再做的時候忘了序列是隨機的了。。然後怎麼搞都是o(

n4) 的。

我們可以將狀態設為f(x,i,l,r),表示在i次操作後,[l,r]<x,l-1和r+1大於等於x的方案數。(不妨認為a[

0]=a

[n+1

]=∞ )這樣的話假如說有跨越區間端點的操作,那麼就一定會使操作中的數≥x。然後令g(x,j)表示讓位置j最終<x的方案數,那麼g(

x,j)

=∑jl

=1∑n

r=jf

(x,q

,l,r

) ,∑x

x∗g(

x+1,

j)−g

(x,j

) 就是答案了。

然而這樣的話狀態數似乎是o(

n4) 的。。但是對於a[

i]=x

而言,可能成為x的位置只在它左右第乙個比它大的位置之間,而且資料隨機。資料隨機就有笛卡爾樹高是o(

lgn) 的,那麼乙個簡單但不嚴謹的想法就是可以把笛卡爾樹看成乙個滿二叉樹,那麼狀態數就是o(

∑log2n

i=12

i−1(

n2i)

2)=o

(∑log2ni

=1n2

2i)=

o(n2

) 。乙個稍微嚴謹一點的想法是基於隨機n個數,那麼第n個數最大的概率是1n

,這樣的話就有o(

∑ni=

1∑ij

=2(∏

j−1k

=2k−

1k)1

jj2)

=o(n

2).所以總的狀態數其實只有o(

n2q)

。 再考慮轉移,f(

x,i,

l,r)

−>((

l−1)

l2+(

r−l+

1)(r

−l+2

)2+(

n−r)

(n−r

+1)2

)f(x

,i+1

,l,r

)−>(l

−1)f

(x,i

+1,j

,r)(

lr)−>(n

−r)f

(x,i

+1,l

,j)(

l≤x注意到後面兩個相當於是對一段區間加同乙個數,類似差分一下什麼的就很好搞了。

**:

#include

#include

using

namespace

std;

#include

#include

#include

typedef

long

long ll;

const

int n=400+5,q=400+5;

int n,q;

const

int mod=1e9+7;

inline ll power(ll prod,int x)

return ans;

}ll f[2][n][n];

int a[n],hash[n];

ll g[n][n];

intstack[n];

int chain[n][n];

inline

void cal(int l,int r,int x)

}for(int l=l;l<=r;++l)

}for(int l=l;l<=r;++l)

for(int r=l;r<=r;++r)

(f[now][l][r]+=(((l-1)*l>>1)+((r-l+1)*(r-l+2)>>1)+((n-r)*(n-r+1)>>1))*f[post][l][r])%=mod;

/*for(int l=l;l<=r;++l)

for(int r=l;r<=r;++r)

if(f[now][l][r])

printf("f(%d,[%d,%d])=%i64d\n",i,l,r,f[now][l][r]);*/

}for(int l=l;l<=r;++l)

for(int r=l;r<=r;++r)

for(int j=l;j<=r;++j)

g[x][j]+=f[now][l][r];

for(int j=l;j<=r;++j)g[x][j]%=mod;

for(int j=l;j<=r;++j)chain[j][++chain[j][0]]=x;

}int main()

sort(hash+1,hash+n+1);

int htot=unique(hash+1,hash+n+1)-hash;

for(int i=n;i;--i)a[i]=lower_bound(hash+1,hash+htot,a[i])-hash;

a[0]=htot,a[n+1]=htot,hash[htot]=-1;

int top=1;

for(int i=1;i<=n;++i)

stack[top++]=i;

}while(--top)cal(stack[top],n+1,a[stack[top]]);

g[htot][1]=power(n*(n+1)>>1,q);

for(int i=n;i>1;--i)g[htot][i]=g[htot][1];

for(int i=1;i<=n;++i)

puts("");

}

總結:

①一定要仔細讀題,注意變數的上下界,是否有特殊約定。

②如果確定不會爆long long的話,可以最後再模,這樣可以減小常數。

③#define rep這種東西感覺挺科學的,以後要學著寫的。

ZJOI2016 解題報告

我大浙的省選題真是超級神仙 這套已經算是比較可做的了。神仙分治題。對於乙個矩形,每次我們從最長邊切開,最短邊不會超過 sqrt 所以對於每個點跑一遍最短路就行了。時間複雜度 o n sqrt log n q sqrt code below include define id i,j i 1 m j ...

ZJOI2019 線段樹 解題報告

聽說有人噴這個題簡單,然後我就跑去做,然後自閉感 rp 霧 理性分析一波,可以發現最後形成的 2 k 個線段樹,對應的操作的乙個子集,按時間順序作用到這顆線段樹上。首先考慮研究一下tag的性質,比如兩個操作時間先後是否沒有影響,操作是否可以以某種形式進行合併,然後啥也沒發現。然後考慮一下一顆樹是否可...

ZJOI2016 大森林 題解

lct 對 lct 有了更深的理解 參考 flashhu 有 n 棵樹,初始各有 1 個編號為 1 的節點,稱它們為生長節點。m 個操作,3 種之一 n le 10 5,m le 2 times 10 5 顯然我們有 o n 2 log n 的暴力 lct 做法,但是好像空間有點著不住 最初的想法是...