bzoj3688 折線統計

2022-05-30 21:18:11 字數 1360 閱讀 1589

二維平面上有n個點(xi, yi),現在這些點中取若干點構成乙個集合s,對它們按照x座標排序,順次連線,將會構成一些連續上公升、下降的折線,設其數量為f(s)。如下圖中,1->2,2->3,3->5,5->6(數字為下圖中從左到右的點編號),將折線分為了4部分,每部分連續上公升、下降。

現給定k,求滿足f(s) = k的s集合個數。

第一行兩個整數n和k,以下n行每行兩個數(xi, yi)表示第i個點的座標。所有點的座標值都在[1, 100000]內,且不存在兩個點,x座標值相等或y座標值相等

輸出滿足要求的方案總數 mod 100007的結果

5 1

5 53 2

4 42 3

1 1

19
對於100%的資料,n <= 50000,0 < k <= 10

線段樹/bit優化dp。

設\(f[i][j][0/1]\)表示考慮了前\(i\)個點,有\(j\)段折線,且最後一段是上公升/下降的方案數。

可以得到乙個很顯然的轉移:

\[f[i][k][0]=\sum_^ f[j][k][0]*[a[i]>a[j]]+f[j][k-1][1]*[a[i]>a[j]]

\]\[f[i][k][1]=\sum_^ f[j][k-1][0]*[a[i]

注意到\(k\)的範圍只有10,可以暴力列舉後兩維,然後用一顆權值線段樹來維護第一維。

#includeusing namespace std;

void read(int &x)

#define write(x) printf("%d\n",x)

#define maxn 100005

const int mod = 100007;

int f[maxn][11][2],n,k;

struct point a[maxn];

inline int cmp(point x,point y)

void modify(int p,int l,int r,int x,int v)

int query(int p,int l,int r,int x,int y)

}t[11][2];

#define n 100000

int main()

}int ans=0;

//for(int i=1;i<=n;i++) printf("%d %d\n",f[i][1][0],f[i][1][1]);

for(int i=1;i<=n;i++) ans=(ans+f[i][k][0]+f[i][k][1])%mod;

write(ans);

return 0;

}

bzoj3688 折線統計

time limit 10 sec memory limit 256 mb submit 119 solved 66 submit status discuss 二維平面上有n個點 xi,yi 現在這些點中取若干點構成乙個集合s,對它們按照x座標排序,順次連線,將會構成一些連續上公升 下降的折線,設...

BZOJ3688 折線統計

portal time limit 10 sec memory limit 256 mb 二維平面上有n個點 xi,yi 現在這些點中取若干點構成乙個集合s,對它們按照x座標排序,順次連線,將會構成一些連續上公升 下降的折線,設其數量為f s 如下圖中,1 2,2 3,3 5,5 6 數字為下圖中從...

BZOJ3688 折線統計(dp bit優化)

傳送門n2 k 的dp是比較好想好寫的 f i,j,0 1 表示劃分了i段,以第j個結尾,最後一段是上公升0 下降1的方案數 f i,j,0 k i 1j 1 y k j f i,k,0 k i 1j 1 y k y j f i 1,k,1 f i,j,1 k i 1 j 1 y k j f i 1...