比較水,就不說了。
就是暴力優化,不知道複雜度為哈對,**也過不了,就不放了。
考慮暴力,即每次每個點向可以一波傳染的點連邊,然後縮點,求無入度的點數即可。
考慮優化,你發現對於兩個點可以在點分樹上乙個點考慮先走到該點再到另乙個點,所以我們可以直接澱粉質,然後雙指標拆點連邊即可。
#include using namespace std;
#define int register int
#define ll long long
#define maxm 6000005
#define maxn 300005
template inline void read (t &t)while (c >= '0' && c <= '9') t *= f;}
template inline void read (t &t,args&... args)
template inline void write (t x)if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template inline void chkmax (t &a,t b)
template inline void chkmin (t &a,t b)
int n,m,r[maxn];
struct edge;
vector e[maxm];
vector g[maxn];
stack s;
bool vis[maxm];
int ind,tot,dfn[maxm],low[maxm],bel[maxm];
void tarjan (int u) }}
ll dep[maxn];
int all,root,siz[maxn],mxs[maxn];
void findroot (int u,int fa)
chkmax (mxs[u],all - siz[u]);
if (!root || mxs[u] < mxs[root]) root = u;
}int cnt,ts[maxn],ps[maxn];
void dfs (int u,int fa,ll dpt)
}void link (int u,int v)
void workit (int u));
sort (ps,ps + cnt,(int x,int y));
for (int i = 0,t = 0;i < cnt;++ i)
for (edge it : g[u])
}signed main()),g[v].push_back ();
m = all = n,findroot (1,0),workit (root),memset (vis,0,sizeof (vis));
for (int i = 1;i <= m;++ i) if (!dfn[i]) tarjan (i);
for (int u = 1;u <= m;++ u) for (int v : e[u]) if (bel[u] != bel[v]) vis[bel[v]] = 1;
int ans = 0;
for (int i = 1;i <= tot;++ i) ans += (!vis[i]);
write (ans),putchar ('\n');
return 0;
}
模擬賽 circle 題解
題意 有n個數,問有多少個x,x leq t 滿足這n個數分別 x後,異或和為s。每個數小於 2 m 數字dp。由於是加法,需要記錄進製,因此從低位到高位dp。只要記錄下有幾個進製,就可以根據這n的數的大小知道究竟是哪幾個進製了。設 dp i,j,0 1 表示考慮到第i位,有j個進製,與t的大小關係...
模擬賽2 題解
這次模擬賽最後一道是提答題,就不寫題解了。orz這題 emmm,我無話可說。小範圍記憶化,大範圍遞迴求解 複雜度 o k sqrt 記 f i,j 表示前 j 個數中不被 a i,a dots,a n 整除的個數,答案即為 f 1,n 狀態轉移方程為 f i,j f i 1,j f i 1,j a ...
2020 10 08 模擬賽 題解
期望100 實際100 老師說是結論題。其實可以直接打表,t i 表示0 63中有t i 對數與起來等於i,然後乘法原理即可。沒什麼難度。include include using namespace std const int maxn 100005 const int mod 1e9 7 cha...