人生第一道黑題祭
本題偏重思維
判斷回文可以考慮它的遞迴定義
只有乙個字元的串是回文串。
只有兩個字元的串,如果這兩個字元相同,也是回文串;
如果 \(s\) 是回文串,那麼在 \(s\) 的開頭和末尾插入乙個相同的字元,形成的新串也是回文串。
乙個可以想到的方法是設 \(f_\) 表示從 \(x\) 到 \(y\) 可不可行
然後 \(\text\) 列舉邊轉移,\(o(m^2),30pts\)
正解是減少邊
分別考慮 \(0->0,1->1,0->1\) 三種邊形成的連通塊
發現它們都滿足
1.如果連通塊是二分圖(不存在奇環),經過偶環並不會對串的長度的奇偶性造成改變,再加上允許一條邊可以走多次,因此沒有必要保留環,只需保留這個連通塊的乙個生成樹即可。
2.如果連通塊不是二分圖(存在奇環),經過奇環會影響串長度的奇偶性,為了方便處理,我們仍然只保留這個連通塊的生成樹,並在這個連通塊的其中乙個點上加乙個自環(從而留下改變奇偶性的機會)。
以此只保留這些邊
可以證明剩下邊不超過 \(2n-2\) 條(別問我)
然後就沒了
#include#include#includeusing namespace std;
const int n = 5005, m = 500005;
int n, m, q, w[n], f[n][n];
char str[n];
inline void read(int &x)
struct node;
queueq;
int h[n], h[n], x[m], y[m];
struct edgee[m << 1], e[m << 1];
inline void adde(int x, int y)
, h[x] = tote;
}inline void add(int x, int y)
, h[x] = tot;
}int bz1[n], col[n];
void color(int x, int c)
}int fa[n][2];
inline int find(int x, int y)
int bz2[n];
inline void build()
else);
} }for(register int i = 1; i <= n; i++)
if (bz1[abs(col[i])] && !bz2[abs(col[i])]) add(abs(col[i]), abs(col[i])), bz2[abs(col[i])] = 1;
}inline void bfs()
); } }}
int main()
); int x, y;
for(register int i = 1; i <= m; i++)
build(), bfs();
for(register int i = 1; i <= q; i++)
}
HNOI2019 校園旅行
某學校的每個建築都有乙個獨特的編號。一天你在校園裡無聊,決定在校園內隨意地漫步。你已經在校園裡呆過一段時間,對校園內每個建築的編號非常熟悉,於是你情不自禁的把周圍每個建築的編號都記了下來 但其實你沒有真的記下來,而是把每個建築的編號除以 2 取餘數得到 0 或 1,作為該建築的標記,多個建築物的標記...
HNOI2019 校園旅行 DP
給定n nn個點,m mm條邊的圖。每個點有0 1 0 10 1的標號,有q qq個詢問,每次詢問點對 u,v u,v u,v 間是否一條路徑 不一定是簡單路徑 滿足路徑經過的點的標號所形成的串是回文串。n 5000,m 5000000 n leq 5000,m leq 5000000 n 5000...
HNOI2019 校園旅行 構造 生成樹 動規
hnoi2019 校園旅行 最樸素的做法就是點對擴充套件 o m 2 發現 n 比較小,我們是否能從 n 下手減少邊數呢?是肯定的 單獨看乙個顏色的聯通塊,如果是二分圖,我們生產樹和原來的效果相同 如果不是二分圖,是會有乙個環的,在樹上隨便圈乙個自環和原來的效果相同 而看不同顏色的連邊,一定是二分圖...