[考试总结]noip模拟58
博客不能再咕了,所以今天趁着还没有忘干净就赶紧补补。
这场考试还是比较凄惨的。。。。
自己认为贝尔数还是比较可做的,然后发现这个模数是个合数。
当场自闭,认为 \(C\) 根本无法计算。。。
然后想了一个比较嗖的方法。。。。
写了一个 \(.py\) 然后直接暴力计算之后取模。。
本以为自己牛逼得一批,然后认为很多分数到手,结果。。。
\(python\) 的除法计算直接化成浮点数,然后我的精度就爆炸了。。。
非常生气!!!
然后 \(T1\) 偏偏是没有往 \(topo\) 那里去想。
Lesson5!
这个就是一个拓扑,一次拓扑之后我们就能找到一个有向图的任意起点的最短路,之后我们记忆化一下。
那么我们使用 \(multiset\) 来维护一下子删点就行。
%: pragma GCC optimize(2)
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register int i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define file(a) FILE *FI = freopen(#a".in","r",stdin); FI = freopen(#a".out","w",stdout);
#define debug cout<<"debug"<<endl
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &x)
{
register type s = 0; register int f = 1; register char ch = gc();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return x = s * f,*this;
}}io;
}
using namespace xin_io; static const int maxn = 1e6+10,inf = 1e9+7,mod = 998244353; const ll llinf = 1e18+7;
auto max = [](int x,int y)->int{return x > y ? x : y;}; auto min = [](int x,int y)->int{return x < y ? x : y;};
namespace xin
{
class xin_edge{public:int next,ver;}edge[maxn];
int head[maxn],rp;
auto add = [](int x,int y) -> void{edge[++rp].ver = y; edge[rp].next = head[x]; head[x] = rp;};
int T,n,m;
int ind[maxn],cind[maxn];
int maxx;
int id[maxn];
std::multiset<int,std::greater<int> >s;
class xin_data
{
public:
int x,tim;
xin_data(){}
xin_data(int x,int tim):x(x),tim(tim){}
};
bool vis[maxn];
auto topo = []() -> void
{
std::queue<xin_data>q;
try(i,1,n) if(!ind[i] and !vis[i]) q.push(xin_data(i,0));
while(q.size())
{
xin_data x = q.front(); q.pop();
// sb(x.x); jb(x.tim);
maxx = max(maxx,x.tim);
go(i,x.x)
if(!--ind[y] and !vis[y])
q.push(xin_data(y,x.tim+1));
}
};
int f[maxn],g[maxn];
auto getid = []() -> void
{
int x = 0,tot = 0;
try(i,1,n) if(!ind[i]) id[++tot] = i;//,cout<<i<<' ';
while(tot < n)
{
x++;
go(i,id[x])
if(!--ind[y]) id[++tot] = y;
}
};
std::pair<int,int>ans = std::make_pair(inf,inf);
std::vector<int>vec[maxn];
int mark[maxn];
inline short main()
{
file(johnny);
io >> T;
while(T--)
{
io >> n >> m;
try(i,1,m)
{
register int x,y; io >> x >> y;
add(x,y); ind[y] ++;
vec[y].push_back(x);
}
if(!m) {cout<<1<<' '<<0<<endl; continue;}
// try(i,1,n) if(!ind[i]) jb(i);
getid();
// try(i,1,n) cout<<id[i]<<' ';
try(i,1,n)
{
register int x = id[i]; f[x] = max(f[x],1);
go(bian,x) f[y] = max(f[y],f[x] + 1);
}
throw(i,n,1)
{
register int x = id[i]; g[x] = max(g[x],1);
go(bian,x) g[x] = max(g[x],g[y] + 1);
}
// try(i,1,n) cout<<f[i]<<' '<<g[i]<<endl;
try(i,1,n) s.insert(g[i]),s.insert(0);
try(i,1,n)
{
register int x = id[i];
for(auto y : vec[x])
if(s.find(f[y] + g[x]) != s.end())
s.erase(s.find(f[y] + g[x]));
else mark[f[y] + g[x]] ++;
if(s.find(g[x]) != s.end())
s.erase(s.find(g[x]));
else mark[g[x]] ++;
register int temp = *s.begin();
if(temp < ans.second) ans.second = temp,ans.first = x;
else if(temp == ans.second) ans.first = min(ans.first,x);
go(bian,x)
{
if(mark[f[x] + g[y]])
mark[f[x] + g[y]] --;
else s.insert(f[x] + g[y]);
}
if(mark[f[x]]) mark[f[x]] --;
else s.insert(f[x]);
}
s.clear();
/*
try(i,1,n)
{
memcpy(ind,cind,sizeof(int) * (n + 1));
// try(j,1,n) jb(ind[j]);
vis[i] = 1; maxx = -inf;
go(bian,i) ind[y] --;
topo();
// jb(maxx);
if(maxx < ans.second) ans = std::make_pair(i,maxx);
// sb(i); jb(maxx);
vis[i] = 0;
}*/
cout<<ans.first<<' '<<ans.second - 1<<endl;
memset(head,0,sizeof(int) * (n + 1)); memset(f,0,sizeof(int) * (n + 1));
memset(ind,0,sizeof(int) * (n + 1)); memset(g,0,sizeof(int) * (n + 1));
try(i,1,n) vec[i].clear();
ans = std::make_pair(inf,inf); rp = 0;
}
return 0;
}
}
signed main() {return xin::main();}
贝尔数
这个暂时只想说说这个的暴力。。。
这个东西组合数是可以计算的。
我们用杨辉三角递推就行,这样是合数也是不用害怕的。。
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define int long long
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register int i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x];i;i=edge[i].next)
namespace xin_io
{
#define file(a) FILE *FI = freopen(#a".in","r",stdin); FI = freopen(#a".out","w",stdout);
#define debug cout<<"debug"<<endl
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &x)
{
register type s = 0; register int f = 1; register char ch = gc();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return x = s * f,*this;
}}io;
}
using namespace xin_io; static const int maxn = 1e6+10,inf = 1e9+7; const ll llinf = 1e18+7;
#define int long long
namespace xin
{
const int mod = 95041567;
int bell[maxn];
int C[maxn/1000+11][maxn/1000+11];
inline short main()
{
file(bell);
int ms = 1010;
C[0][0] = 1;
try(i,1,ms) try(j,i,ms) C[j][i] = (C[j-1][i] + C[j-1][i-1]) % mod;
bell[0] = bell[1] = 1;
try(n,1,ms)
{
int tot = 0;
try(k,0,n) (tot += C[n][k] * bell[k] % mod) %= mod;
bell[n+1] = tot;
}
int T; io >> T;
while(T--)
{
register int x; io >> x;
cout<<bell[x+1]<<endl;
}
return 0;
}
}
signed main() {return xin::main();}
穿越广场
\(Ac\) 自动机的 \(dp\)
\[(f[i+1][ j ][t[k].son[0]][l|state[t[k].son[0]]] += f[i][j][k][l]) \%= mod;\\
(f[i+1][j+1][t[k].son[1]][l|state[t[k].son[1]]] += f[i][j][k][l]) \%= mod;
\]
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register int i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define file(x) FILE *FI = freopen(#x".in","r",stdin); FI = freopen(#x".out","w",stdout);
#define debug cout<<"debug"<<endl
#define jb(x) cout<<#x" = "<<x<<endl;
#define sb(x) cout<<#x" = "<<x<<' '
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &x)
{
register type s = 0; register int f = 1; register char ch = gc();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return x = s * f,*this;
}}io;
#define scanf ak = scanf
}
using namespace xin_io; static const int maxn = 2e3+10,inf = 1e9+7; const ll llinf = 1e18+7;
#define int long long
namespace xin
{
const int mod = 1e9+7;
class xin_trie
{
public:
int son[2];
int fail;
}t[maxn];
int cnt = 1;
int state[maxn];
inline void insert(char *s,int num)
{
register int u = 1;
for(register int i=0;s[i];++i)
{
register int bian = s[i] == 'R';
if(!t[u].son[bian]) t[u].son[bian] = ++cnt;
u = t[u].son[bian];
}
state[u] |= num;
// jb(state[u]);
}
inline void getfail()
{
std::queue < int > q; q.push(1);
t[0].son[0] = t[0].son[1] = 1;
while(q.size())
{
register int u = q.front(); q.pop();
for(register int i=0;i<=1;++i)
if(t[u].son[i])
t[t[u].son[i]].fail = t[t[u].fail].son[i],q.push(t[u].son[i]);
else
t[u].son[i] = t[t[u].fail].son[i];
}
}
int n,m,T;
int f[201][201][201][4];
auto work = []() -> void
{
int ans = 0;
try(i,1,cnt)
{
for(register int j=i;j;j=t[j].fail)
state[i] |= state[j];
// jb(state[i]);
}
f[0][0][1][0] = 1;
try(i,0,n+m-1) try(j,0,m) try(k,1,cnt) try(l,0,3)
{
(f[i+1][ j ][t[k].son[0]][l|state[t[k].son[0]]] += f[i][j][k][l]) %= mod;
(f[i+1][j+1][t[k].son[1]][l|state[t[k].son[1]]] += f[i][j][k][l]) %= mod;
}
try(i,1,cnt) (ans += f[n+m][m][i][3]) %= mod;//,jb(f[n+m][m][i][3]);
printf("%lld\n",ans);
};
char s1[maxn],s2[maxn];
auto clear = []() -> void
{
memset(f,0,sizeof(f)); cnt = 1; memset(t,0,sizeof(t));
memset(state,0,sizeof(state));
};
inline short main()
{
file(square);
scanf("%lld",&T);
while(T--)
{
clear();
scanf("%lld%lld",&m,&n);
scanf("%s%s",s1,s2);
insert(s1,1); insert(s2,2);
getfail();
work();
}
return 0;
}
}
signed main() {return xin::main();}
舞动的夜晚
这个题目的部分分数就是一个二分图的最大匹配,这个我们可以用 \(dinic\) 跑一个最大流。
但其实我们还有一个很好的方法就是匈牙利算法,这个可以在严格 \(\mathcal O(nm)\) 的复杂度中计算出二分图的最大匹配。
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register int i=a;i<=b;++i)
#define throw(i,a,b) for(register int i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define file(a) FILE *FI = freopen(#a".in","r",stdin); FI = freopen(#a".out","w",stdout);
#define debug cout<<"debug"<<endl
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &x)
{
register type s = 0; register int f = 1; register char ch = gc();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return x = s * f,*this;
}}io;
}
using namespace xin_io; static const int maxn = 1e6+10,inf = 1e9+7,mod = 998244353; const ll llinf = 1e18+7;
namespace xin
{
class xin_edge{public:int next,ver;}edge[maxn];
class xin_data{public:int x,y;}d[maxn];
int head[maxn],rp;
auto add = [](int x,int y) -> void{edge[++rp].ver = y; edge[rp].next = head[x]; head[x] = rp;};
bool vis[maxn];
int mat[maxn],ans = 0;
int zhuanx,zhuany;
bool dfs(int x)
{
go(i,x) if(!vis[y] and zhuanx != x and zhuany != y)
{
vis[y] = 1;
if(!mat[y] or dfs(mat[y])) {mat[y] = x; return true;}
}
return false;
}
int n,m,t;
int out[maxn],top;
inline short main()
{
file(night);
io >> n >> m >> t;
try(i,1,t)
{
register int x,y; io >> x >> y;
y += n; add(x,y); add(y,x);
d[i].x = x; d[i].y = y;
}
// vis[2] = vis[4] = 1;
// mat[4] = 2;
// zhuanx = 2; zhuany = 4;
try(i,1,n)
{
memset(vis,0,sizeof(bool) * (n + m + 1));
if(dfs(i)) ans ++;
}
// try(i,1,n+m) sb(i),jb(mat[i]);
int comp = ans;
try(i,1,t)
{
memset(mat,0,sizeof(int) * (n + m + 1));
zhuanx = d[i].x; zhuany = d[i].y; ans = 0;
try(i,1,n)
{
memset(vis,0,sizeof(bool) * (n + m + 1));
if(dfs(i)) ans ++;
}
if(ans + 1 < comp) out[++top] = i;
}
// cout<<ans<<endl;
cout<<top<<endl;
try(i,1,top)
cout<<out[i]<<' ';
return 0;
}
}
signed main() {return xin::main();}