SDOI2009 虔誠的墓主人

2022-04-30 03:33:09 字數 1595 閱讀 6128

題目大意:\(n\times m\)的點陣,有的點是樹木,定義乙個空點的度數為正上,正左,正右,正下分別有\(k\)個點的選法

求點陣的總度數.

挺好的一道題,排列組合和資料結構糅合在一塊

#include #include #include #define lowbit(x) x & -x//巨集定義樹狀陣列操作

using std::sort;

using std::min;

const int n = 1e6 + 10;

struct nodea[n];

int n, m, w, k, col;

int c[n][16];

int tmp[n], xcnt[n], ycnt[n], h[n], r[n], bit[n];

inline void ins(int a, int b)

inline int ask(int a)

return ans;

}inline bool cmp1(node a, node b)

inline bool cmp2(node a, node b)

inline bool c***(node a, node b)

inline void pre()

} return;

}//二項式定理預處理組合數

inline void disp()

tmp[i] = tt;

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

sort(a + 1, a + w + 1, cmp2);

tt = 0;

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

tmp[i] = tt;

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

col = tt;//記錄樹狀陣列的「n」

return;

}//離散化

int main()

scanf("%d", &k);

pre();

disp();

sort(a + 1, a + w + 1, c***);

int tt = 0, ans = 0;

for(int i = 1, lh, lv; i <= w; ++i)else

ins(lh, lv - r[lh]);//如果不符合,就減去之前符合的,變成0

r[lh] = lv;

tt ++;//別忘了

if(i == w || a[i].x != a[i + 1].x || a[i + 1].y - a[i].y <= 1 || tt continue;

ans += c[tt][k] * c[xcnt[a[i].x] - tt][k] * (ask(a[i + 1].y - 1) - ask(a[i].y));

}//這裡上面空地正好是a[i + 1].y - 1,下面是a[i].y + 1,由於樹狀陣列的操作,所以這樣寫

printf("%d", ans & 2147483647);//自然溢位

return 0;

}

洛谷 SDOI2009 虔誠的墓主人

初見安 這裡是傳送門 洛谷p2154 sdoi2009 虔誠的墓主人 題意很簡單 在n m的網格上,求所有未標記點的權值和。乙個未標記點的權值為 設其上下左右有 首先資料範圍很夠,k很小,我們就預處理 暴力做法列舉每個格點的話,我們可以預處理出每行每列標記點的字首和然後離散化,這樣的話複雜度就是 我...

LG2154 SDOI2009 虔誠的墓主人

洛谷 如果您沒有看懂題,請反覆閱讀題面及樣例 可以發現,對於某乙個點,它的答案就是上下左右幾個組合數乘起來。這樣直接做複雜度顯然 考慮怎麼優化這個東西。我們可以固定左右,在某兩個左右之間維護上下有多少個,這樣子的話左右的貢獻就是不變的,而且你最多隻會變化 o n 次左右邊界,複雜度 這樣的話,每次查...

BZOJ 1227 虔誠的墓主人

題解 長這樣的題好像都有固定套路 所有點按座標排序 處理組合數,然後用樹狀陣列維護奇怪的資訊 編不下去了 黃學長的題解 ac code include include include using namespace std inline void read int x const int mo 21...