題目大意:\(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...