[hnoi2019]校園旅行
最樸素的做法就是點對擴充套件\(o(m^2)\)
發現\(n\)比較小,我們是否能從\(n\)下手減少邊數呢?是肯定的
單獨看乙個顏色的聯通塊,如果是二分圖,我們生產樹和原來的效果相同
如果不是二分圖,是會有乙個環的,在樹上隨便圈乙個自環和原來的效果相同
而看不同顏色的連邊,一定是二分圖,再生產樹就好了
總邊數是\(n\)級的,總複雜度\(o(n^2)\)
#include#includetypedef int ll;
const ll maxn=5009,maxm=500009;
inline ll read()
while(c>='0' && c<='9')
return x*f;
}ll f;
ll visit[maxn],col[maxn],a[maxn],fa[maxn];
ll n,m,q,top;
ll mark[maxn][maxn];
struct edgee[maxm];
ll get_fa(ll x)
struct mpdis[maxm<<1];
ll num;
ll head[maxn];
inline void add(ll u,ll v); head[u]=num;
} void dfs1(ll u,ll c)
ll fx(get_fa(u)),fy(get_fa(v));
if(fx!=fy);
}dfs1(v,3-c);
} }void dfs2(ll u);
fa[fx]=fy;
}dfs2(v);
} }}g1,g2;
std::queueque;
inline void build()
} memset(visit,false,sizeof(visit));
for(ll i=1;i<=n;++i) fa[i]=i;
for(ll i=1;i<=n;++i)
if(!visit[i])
g1.dfs2(i);
for(ll i=1;i<=top;++i)
for(ll u=1;u<=n;++u)); mark[u][u]=true;
for(ll i=g2.head[u];i;i=g2.dis[i].nxt));
mark[v][u]=mark[u][v]=true;
}} }
while(que.size()));}}
}} }
}char s[maxn];
int main()
build();
while(q--)
return 0;
}
HNOI2019 校園旅行
人生第一道黑題祭 本題偏重思維 判斷回文可以考慮它的遞迴定義 只有乙個字元的串是回文串。只有兩個字元的串,如果這兩個字元相同,也是回文串 如果 s 是回文串,那麼在 s 的開頭和末尾插入乙個相同的字元,形成的新串也是回文串。乙個可以想到的方法是設 f 表示從 x 到 y 可不可行 然後 text 列...
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...