NC14306 debug
图论,没题解,还没懂
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <map>
using namespace std;
const int MAXN = 260;
const int MAXM = 11000;
const int MAXS = 30;
map<string, int> h;
int n;
int m;
bool a[MAXN][MAXN];
bool ena[MAXN];
bool g[MAXN][MAXN];
bool chk[MAXN];
int mat[MAXN];
int q[MAXN];
int f[MAXN];
int getHash(string &s)
{
if (h[s] == 0) return h[s] = (++n);
else return h[s];
}
// 手写了一个FSA
void init()
{
h.clear();
string s;
int cur = 1;
bool d = true;
n = 1;
memset(a, false, sizeof(a));
memset(ena, false, sizeof(ena));
memset(f, 0xff, sizeof(f));
memset(q, 0xff, sizeof(q));
while (cin >> s && s != "END")
{
if (s == "STATEMENT")
{
if (!d) // 用来添加节点
{
a[cur][++n] = 1;
cur = n;
}
ena[cur] = true; // 当前这个节点有statement要处理
}
else if (s == "GOTO")
{
cin >> s;
a[cur][getHash(s)] = true;
cur = 0;
}
else if (s == "IF")
{
cin >> s;
cin >> s;
a[cur][getHash(s)] = true;
d = false;
}
else
{
int l = s.size();
s = s.substr(0, l - 1);
int v = getHash(s);
a[cur][v] = true;
cur = v;
d = true;
}
}
ena[1] = true; // ?
}
int cnt;
void dfs(int v)
{
if (chk[v]) return;
chk[v] = true;
for (int i = 1; i <= n; ++i)
if (ena[i] && a[v][i])
dfs(i);
q[++cnt] = v;
}
// 反图
void dfs2(int v)
{
if (chk[v]) return;
f[v] = cnt; // 连通分量的编号
chk[v] = true;
for (int i = 1; i <= n; ++i)
if (ena[i] && a[i][v])
dfs2(i);
}
// 类匈牙利...
bool dfs3(int v)
{
for (int i = 1; i <= cnt; ++i)
if (g[v][i] && !chk[i])
{
chk[i] = true;
int tmp = mat[i];
mat[i] = v;
if (tmp == -1) return true;
if (dfs3(tmp)) return true;
mat[i] = tmp;
}
return false;
}
void solve()
{
if (ena[0])
{
printf("-1\n");
return;
}
int ne = 0;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
for (int k = 1; k <= n; ++k)
if (a[j][i] && a[i][k]) a[j][k] = 1; // 可达矩阵
if (ena[i]) ++ne;
}
cnt = 0;
memset(chk, 0, sizeof(chk));
dfs(1);
if (cnt != ne)
{
printf("-1\n");
return;
}
// q:需要抵达的点
memset(chk, 0, sizeof(chk));
cnt = 0;
// scc缩点图
// kosaraju??
for (int i = ne; i >= 1; --i)
if (!chk[q[i]])
{
++cnt;
dfs2(q[i]);
}
// cout<<"cnt=="<<cnt<<endl;
memset(g, 0, sizeof(g));
for (int i = 1; i <= n; ++i)
if (ena[i])
for (int j = 1; j <= n; ++j)
if (ena[j] && a[i][j] && f[i] != f[j])
g[f[i]][f[j]] = true;
memset(mat, 0xff, sizeof(mat));
int ans = cnt;
for (int i = 1; i <= cnt; ++i)
{
memset(chk, 0, sizeof(chk)); if (dfs3(i)) --ans;
}
printf("%d\n", ans);
}
int main()
{
int tt;
cin >> tt;
while (tt--)
{
init();
solve();
}
return 0;
}
NC15075 导一导
首先推导就有点。。高数还是没学好
有n有i的卷积就能fft?
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, k, fac[N], ifac[N], a[N], b[N], bb[N], c[N];
const int mod = 998244353, G = 3;
int up, w[N], rev[N];
int fpw(int a, int b)
{
int ans = 1;
while(b)
{
if(b&1) ans = 1ll*ans*a%mod;
a = 1ll*a*a%mod;
b >>= 1;
}
return ans;
}
namespace poly
{
void init(int n)
{
up = 1; int l = 0;
while(up<=n) up <<= 1, l++;
for(int i=0; i<up; i++) rev[i] = (rev[i>>1]>>1)|((i&1)<<(l-1));
int wn = fpw(G, mod>>l); w[up>>1] = 1;
for(int i=(up>>1)+1; i<up; i++) w[i] = 1ll*w[i-1]*wn%mod;
for(int i=(up>>1)-1; i>=1; i--) w[i] = w[i<<1];
}
void clear(int *a, int n) { memset(a, 0, n<<2); }
int getlen(int n) { return 1<<(32-__builtin_clz(n)); }
inline void mul(int *a, int n, int x, int *b) { while(n--) *b++ = 1ll**a++*x%mod; }
inline void dot(int *a, int *b, int n, int *c) { while(n--) *c++ = 1ll**a++**b++%mod; }
void DFT(int *a, int l)
{
static unsigned long long tmp[N];
int u = __builtin_ctz(up/l), t;
for(int i=0; i<l; i++) tmp[i] = a[rev[i]>>u];
for(int i=1; i^l; i<<=1)
for(int j=0, d=i<<1; j^l; j+=d)
for(int k=0; k<i; k++)
t = tmp[i|j|k]*w[i|k]%mod, tmp[i|j|k] = tmp[j|k]+mod-t, tmp[j|k] += t;
for(int i=0; i<l; i++) a[i] = tmp[i]%mod;
}
void IDFT(int *a, int l)
{
reverse(a+1, a+l); DFT(a, l);
mul(a, l, mod-mod/l, a);
}
}
int comb(int n, int m)
{
if(n<m||n<0||m<0) return 0;
return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> k;
poly::init(n+k);
fac[0] = 1;
for(int i=1; i<=n+k; i++) fac[i] = 1ll*fac[i-1]*i%mod;
ifac[n+k] = fpw(fac[n+k], mod-2);
for(int i=n+k-1; i>=0; i--) ifac[i] = 1ll*ifac[i+1]*(i+1)%mod;
for(int i=1; i<=k; i++)
{
cin >> a[i];
a[i] = 1ll*a[i]*ifac[i-1]%mod;
}
poly::DFT(a, up);
for(int i=0; i<=n; i++)
{
b[i] = comb(n, i);
if((n-i)%4>1) b[i] = mod - b[i];
if(i&1) b[i] = mod - b[i];
}
for(int i=0; i<=n; i+=2) bb[i] = b[i];
poly::DFT(bb, up);
for(int i=0; i<up; i++) c[i] = 1ll*a[i]*bb[i]%mod;
poly::IDFT(c, up);
for(int i=1; i<=n+k; i++) cout << 1ll*c[i]*fac[i-1]%mod << " \n"[i==n+k];
poly::clear(bb, up);
for(int i=1; i<=n; i+=2) bb[i] = b[i];
poly::DFT(bb, up);
for(int i=0; i<up; i++) c[i] = 1ll*a[i]*bb[i]%mod;
poly::IDFT(c, up);
for(int i=1; i<=n+k; i++) cout << 1ll*c[i]*fac[i-1]%mod << " \n"[i==n+k];
return 0;
}