ZJOI2016 解題報告

2022-04-29 22:21:08 字數 3066 閱讀 4611

我大浙的省選題真是超級神仙……這套已經算是比較可做的了。

神仙分治題。

對於乙個矩形,每次我們從最長邊切開,最短邊不會超過 \(\sqrt\),所以對於每個點跑一遍最短路就行了。

時間複雜度 \(o(n\sqrt\log n+q\sqrt)\)

\(code\ below:\)

#include #define id(i,j) (((i)-1)*m+(j))

using namespace std;

const int maxn=20000+10;

const int maxm=100000+10;

const int inf=0x3f3f3f3f;

int n,m,q,val[maxn][4],dis[maxn],vis[maxn],ans[maxm];

int nx[4]=,ny[4]=;

struct node

};inline bool operator < (const node &a,const node &b)

struct queryq[maxm],q1[maxm],q2[maxm];

inline int read()

while(isdigit(ch))

return (f==1)?x:-x;

}inline void dijkstra(int sx,int sy,int lx,int ly,int rx,int ry)

} }}void solve(int lx,int ly,int rx,int ry,int ql,int qr)

if(rx-lx>ry-ly)

for(int i=ql;i<=qr;i++)

for(int i=1;i<=cnt1;i++) q[ql+i-1]=q1[i];

for(int i=1;i<=cnt2;i++) q[ql+cnt1+i-1]=q2[i];

solve(lx,ly,mid,ry,ql,ql+cnt1-1);

solve(mid+1,ly,rx,ry,ql+cnt1,ql+cnt1+cnt2-1);

} else

for(int i=ql;i<=qr;i++)

for(int i=1;i<=cnt1;i++) q[ql+i-1]=q1[i];

for(int i=1;i<=cnt2;i++) q[ql+cnt1+i-1]=q2[i];

solve(lx,ly,rx,mid,ql,ql+cnt1-1);

solve(lx,mid+1,rx,ry,ql+cnt1,ql+cnt1+cnt2-1); }}

int main() }}

inline void solve()

}void dfs(int x)

sta[++top]=x;dfs(x+1);

top--;dfs(x+1);

}int main()

for(int i=1;i神仙 \(dp\) 系列。

\(f[x][p][l][r]\) 表示經過 \(p\) 輪操作後 \(\text_^\leq x<\text(a_,a_)\) 的方案數。

那麼 \(x\) 可以列舉省掉一維,\(p\) 可以滾動陣列,那麼實際只有兩位。我們先看 \(o(n^4)\) 的解法。

\(f[p][l][r]\) 可以由三項轉移:

區間左右端點在 \([1,l-1]\) 或 \([l,r]\) 或 \([r+1,n]\):\(f[p][l][r]=[++]\times f[p-1][l][r]\)

區間右端點在 \(l-1\):\(f[p][l][r]=\sum_^(i-1)\times f[p-1][i][r]\)

區間左端點在 \(r+1\):\(f[p][l][r]=\sum_^(n-i)\times f[p-1][l][i]\)

現在看 \(o(n^3)\) 的解法。

不容易發現可以把 \(x\) 一起轉移,然後就 \(o(n^3)\) 的解法了。

**是 \(o(n^4)\) 的。

\(code\ below:\)

#include #define int long long

using namespace std;

const int maxn=400+10;

const int mod=1e9+7;

int n,m,a[maxn],mp[maxn],cnt[maxn],c[maxn][maxn],sum[maxn][maxn],f[2][maxn][maxn],g[maxn][maxn];

bool is[maxn][maxn];

/*cnt[i] = i * (i + 1) / 2

f(i, l, r) += f(i - 1, l, r) * (cnt[r - l + 1] + cnt[n - r] + cnt[l - 1]);

f(i, l, r) += \sum _ ^ f(i - 1, u, r) * (u - 1)

f(i, l, r) += \sum _ ^ f(i - 1, l, v) * (n - v)

*/inline void solve(int x,int l,int r)

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

//[l, i] [i, r]

for(int i=l-1;i<=r;i++)

for(int j=l-1;j<=r;j++) sum[i][j]=0;

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

for(int j=l;j<=r;j++) sum[i][j]=(sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+f[m&1][i][j])%mod;

for(int i=l;i<=r;i++) g[i][a[x]]=((g[i][a[x]]+sum[i][r]-sum[l-1][r]-sum[i][i-1]+sum[l-1][i-1])%mod+mod)%mod;

}signed main()

int tmp,val,ans;

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

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

printf("\n");

return 0;

}

題解戳這裡

ZJOI2016 線段樹 解題報告

很久以前看過題面然後沒有仔細想,再做的時候忘了序列是隨機的了。然後怎麼搞都是o n4 的。我們可以將狀態設為f x,i,l,r 表示在i次操作後,l,r x,l 1和r 1大於等於x的方案數。不妨認為a 0 a n 1 這樣的話假如說有跨越區間端點的操作,那麼就一定會使操作中的數 x。然後令g x,...

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 做法,但是好像空間有點著不住 最初的想法是...

ZJOI2016一試 醬油記

day1 上午rzz stilwell?講數學,就推 cai 出了第一道。然後聽懂了一點點就開始碎覺了。聽到雜題的時候就又復活辣 下午感覺畫風明顯不對啊。怎麼變成dp了。然後還有樹分治。day2 上午居然講底層運算。講到實數就開始碎覺了。不過感覺o2很茲瓷哦 然後還有分塊,不過裡面的數國隊都講過辣,...