T1 lesson5!

开始以为是个无向图,直接不懂,跳去T2了。

之后有看了一眼发现可暴力,于是有了\(80pts\)。

发现这个图是有拓扑序的,于是可以用拓扑排序找最长路径。先找原图内在最长路径上的点,挨个删了跑拓扑排,看哪个最短。

正解太nb了待补。

\(code:\)

80pts

#include<bits/stdc++.h>
using namespace std; namespace IO{
inline int read(){
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
inline void write(int x,char sp){
char ch[20]; int len=0;
if(x<0){ putchar('-'); x=~x+1; }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
}
inline int max(int x,int y){ return x<y?y:x; }
inline int min(int x,int y){ return x<y?x:y; }
inline void swap(int& x,int& y){ x^=y^=x^=y; }
inline void ckmax(int& x,int y){ x=x<y?y:x; }
inline void ckmin(int& x,int y){ x=x<y?x:y; }
} using namespace IO; const int NN=1e5+5,MM=5e5+5;
int t,n,m,mx,ans,pos,ban,idx,to[MM],nex[MM],head[NN],dis[NN],pre[NN];
int l,r,q[NN],in[NN],deg[NN];
bool vis[NN];
vector<int>vec;
inline void add(int a,int b){
to[++idx]=b; nex[idx]=head[a]; head[a]=idx; ++in[b];
} void topo(){
l=1; r=0;
for(int i=1;i<=n;i++)
if(!in[i]&&ban!=i) pre[i]=0, dis[i]=0, q[++r]=i;
while(l<=r){
int x=q[l++];
if(dis[x]>mx) mx=dis[x];
for(int i=head[x];i;i=nex[i]) if(in[to[i]]&&ban!=to[i]){
--in[to[i]];
if(!in[to[i]]){
pre[to[i]]=x;
dis[to[i]]=dis[x]+1;
q[++r]=to[i];
}
}
}
} signed main(){
FILE *R=freopen("johnny.in","r",stdin);
FILE *W=freopen("johnny.out","w",stdout);
t=read();
while(t--){
n=read(); m=read();
mx=ban=idx=0; vec.clear();
for(int i=1;i<=n;i++) in[i]=head[i]=vis[i]=0;
for(int a,b,i=1;i<=m;i++)
a=read(),b=read(), add(a,b);
for(int i=1;i<=n;i++) deg[i]=in[i];
topo(); ans=mx; pos=INT_MAX;
for(int i=1;i<=n;i++) if(dis[i]==mx){
int x=i;
while(x) vec.push_back(x), x=pre[x];
}
for(int i=0;i<vec.size();i++) if(!vis[vec[i]]){
ban=vec[i]; mx=0; vis[ban]=1;
for(int j=1;j<=n;j++) in[j]=deg[j];
for(int j=head[ban];j;j=nex[j]) --in[to[j]];
topo();
if(mx<ans||(mx==ans&&ban<pos)) ans=mx, pos=ban;
}
write(pos,' '); write(ans,'\n');
}
}


T2 贝尔数

模数不是质数就很搞。。

发现分解质因数后模数是五个一次的两位质数相乘,题目还给了模质数意义下的同余公式,于是可以先求出模五个质数意义下这一位贝尔数的值,然后再用中国剩余定理解个同余方程合并即可。

对每个质数可以先预处理前四十多个贝尔数,然后矩阵加速递推。

个人认为挺神的题(主要是数学跟矩阵都太菜了

\(code:\)

T2

#include<bits/stdc++.h>
#define int long long
using namespace std; namespace IO{
inline int read(){
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
inline void write(int x,char sp){
char ch[20]; int len=0;
if(x<0){ putchar('-'); x=~x+1; }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
}
inline int max(int x,int y){ return x<y?y:x; }
inline int min(int x,int y){ return x<y?x:y; }
inline void swap(int& x,int& y){ x^=y^=x^=y; }
inline void ckmax(int& x,int y){ x=x<y?y:x; }
inline void ckmin(int& x,int y){ x=x<y?x:y; }
} using namespace IO; const int NN=1010,mod=95041567;
int T,n,nul,c[50][50],bell[50],pre[6],calc[6];
int pri[6]={0,31,37,41,43,47}; namespace Crt{
int exgcd(int a,int b,int& x,int& y){
if(!b){
x=1; y=0;
return a;
}
int g=exgcd(b,a%b,x,y),z;
z=y; y=x-a/b*y; x=z;
return g;
}
void init(){
bell[0]=1;
for(int i=0;i<50;i++) c[i][0]=1;
for(int i=1;i<50;i++) for(int j=1;j<=i;j++)
c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
for(int i=1;i<50;i++) for(int j=0;j< i;j++)
(bell[i]+=c[i-1][j]*bell[j]%mod)%=mod;
for(int i=1;i<6;i++){
int g=exgcd(pri[i],mod/pri[i],nul,pre[i]);
pre[i]=(pre[i]%mod+mod)%mod; pre[i]=(mod/pri[i])*pre[i]%mod;
}
}
int solve(){
int res=0;
for(int i=1;i<6;i++) (res+=pre[i]*calc[i])%=mod;
return res;
}
} using namespace Crt; namespace Matrix{
struct matrix{
int s[50][50];
void clr(){ memset(s,0,sizeof(s)); }
void pre(){ clr(); for(int i=0;i<50;i++) s[i][i]=1; }
void print(){for(int i=0;i<50;++i)for(int j=0;j<50;++j)write(s[i][j],j==49?'\n':' ');}
}mat[6],base[6];
matrix mul(matrix x,matrix y,int z){
matrix res; res.clr();
for(int i=0;i<50;i++)
for(int k=0;k<50;k++)
for(int j=0;j<50;j++)
(res.s[i][j]+=x.s[i][k]*y.s[k][j]%z)%=z;
return res;
}
void qpow(matrix& a,matrix b,int c,int d){
while(c){
if(c&1) a=mul(a,b,d);
b=mul(b,b,d);
c>>=1;
}
}
void prework(){
for(int i=1;i<6;i++){
for(int j=0;j<pri[i];j++) mat[i].s[1][j]=bell[j]%pri[i];
base[i].pre();
base[i].s[1][0]=base[i].s[0][pri[i]-1]=base[i].s[1][pri[i]-1]=1;
for(int j=1;j<pri[i]-1;j++) base[i].s[j+1][j]=1;
}
}
} using namespace Matrix; signed main(){
FILE *R=freopen("bell.in","r",stdin);
FILE *W=freopen("bell.out","w",stdout);
T=read(); init();
while(T--){
n=read(); prework();
for(int i=1;i<6;i++){
qpow(mat[i],base[i],n/pri[i],pri[i]);
calc[i]=mat[i].s[1][n%pri[i]];
}
write(solve(),'\n');
}
return 0;
}


T3 穿越广场

考完后发现这好像是个AC自动机套路题,但奈何时间久远,学的时候写的太快没多思考总结,于是SB了。

设\(f_{i,j,k,l}\)为\(DP\)到第\(i\)位,填了\(j\)个\(R\),在自动机中走到第\(k\)个节点,结束状态为\(l\)的方案数。

\(l\)为二进制状态,有两位。

于是有

\(\huge{f_{i,j,k,l} \to f_{i+1,j,to[k]['D'],l|end[to[k]['D']]}}\)

\(\huge{f_{i,j,k,l} \to f_{i+1,j+1,to[k]['R'],l|end[to[k]['R']]}}\)

初始状态\(f_{0,0,1,0}=1\)。

注意每个点继承它\(fail\)的状态即可。

\(code:\)

T3

#include<bits/stdc++.h>
#define int long long
#define ULL unsigned long long
using namespace std; namespace IO{
inline int read(){
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
inline void write(int x,char sp){
char ch[20]; int len=0;
if(x<0){ putchar('-'); x=~x+1; }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
}
inline int max(int x,int y){ return x<y?y:x; }
inline int min(int x,int y){ return x<y?x:y; }
inline void swap(int& x,int& y){ x^=y^=x^=y; }
inline void ckmax(int& x,int y){ x=x<y?y:x; }
inline void ckmin(int& x,int y){ x=x<y?x:y; }
} using namespace IO; const int NN=110,p=1e9+7;
int t,n,m,ext,ans,f[NN<<1][NN][NN<<1][4];
char ch[NN]; namespace AC_automaton{
int root,tot,to[NN<<1][2],fail[NN<<1],end[NN<<1];
void insert(char *s){
int len=strlen(s),u=1;
for(int i=0;i<len;i++){
int now=(s[i]=='R');
if(!to[u][now]) to[u][now]=++tot, end[tot]=0;
u=to[u][now];
}
end[u]=root?2:1;
if(!root) root=1;
}
void build(){
queue<int>q;
if(to[root][0]) q.push(to[root][0]), fail[to[root][0]]=root;
else to[root][0]=root;
if(to[root][1]) q.push(to[root][1]), fail[to[root][1]]=root;
else to[root][1]=root;
while(!q.empty()){
int u=q.front(); q.pop();
end[u]|=end[fail[u]];
if(to[u][0]) fail[to[u][0]]=to[fail[u]][0], q.push(to[u][0]);
else to[u][0]=to[fail[u]][0];
if(to[u][1]) fail[to[u][1]]=to[fail[u]][1], q.push(to[u][1]);
else to[u][1]=to[fail[u]][1];
}
}
} using namespace AC_automaton; signed main(){
FILE *R=freopen("square.in","r",stdin);
FILE *W=freopen("square.out","w",stdout);
t=read();
while(t--){
m=read(); n=read(); tot=1; root=0; ext=n+m; ans=0;
memset(f,0,sizeof(f));
memset(to,0,sizeof(to));
memset(fail,0,sizeof(fail));
scanf("%s",ch); insert(ch);
scanf("%s",ch); insert(ch);
build(); f[0][0][1][0]=1;
for(int i=0;i<ext;i++)
for(int j=0;j<=m;j++){
if(j>i||i-j>n) continue;
for(int k=1;k<=tot;k++)
for(int u=0;u<4;u++){
(f[i+1][j ][to[k][0]][u|end[to[k][0]]]+=f[i][j][k][u])%=p;
(f[i+1][j+1][to[k][1]][u|end[to[k][1]]]+=f[i][j][k][u])%=p;
}
}
for(int i=1;i<=tot;i++) (ans+=f[ext][m][i][3])%=p;
write(ans,'\n');
}
return 0;
}


T4 舞动的夜晚

先跑最大流,然后在残量网络上跑\(tarjan\),如果边在\(SCC\)里说明它没有影响。

改的有点ex,待补

2021.9.21考试总结[NOIP模拟58]的更多相关文章

  1. 2021.8.21考试总结[NOIP模拟45]

    T1 打表 由归纳法可以发现其实就是所有情况的总和. $\frac{\sum_{j=1}^{1<<k}(v_j-v_{ans})}{2^k}$ $code:$ 1 #include< ...

  2. 2021.7.21考试总结[NOIP模拟22]

    终于碾压小熠了乐死了 T1 d 小贪心一波直接出正解,没啥好说的(bushi 好像可以主席树暴力找,但我怎么可能会呢?好像可以堆优化简单找,但我怎么可能想得到呢? 那怎么办?昨天两道单调指针加桶,我直 ...

  3. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  4. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  5. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

  6. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  7. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  8. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  9. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

随机推荐

  1. Asp.net MVC Vue Axios无刷新请求数据和响应数据

    Model层Region.cs using System; using System.Collections.Generic; using System.Linq; using System.Web; ...

  2. JS015. 数据存储方式与位置(堆内存、栈内存、指针)

    数据 - 基本类型 Undefined  ,  Null  ,  String  ,  Number  ,  Boolean  ,  Symbol (ES 6)  , 基本数据类型存储在栈内存中. 数 ...

  3. js判断苹果端,安卓端

    <script type="text/javascript"> var browser = { versions : function() { var u = navi ...

  4. 创建一个Orchard Core CMS 应用程序

    开始使用Orchard Core作为NuGet软件包 在本文中,我们将看到使用Orchard Core提供的NuGet包创建CMS Web应用程序是多么容易. 你可以在这里找到Chris Payne写 ...

  5. Writing in the Science 01

    INTRODUCTION What makes good writing? Good writing communicates an idea clearly and effectively. Goo ...

  6. pip3 install beautifulsoup4 出现错误 There was a problem confirming the ssl certificate

    chenhuimingdeMacBook-Pro:groceryList Mch$ sudo pip3 install beautifulsoup4 The directory '/Users/Mch ...

  7. 关于URL encode和parse

    from urllib import parses = 'https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&tn=baidu& ...

  8. disruptor笔记之四:事件消费知识点小结

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. 牛客练习赛89E-牛牛小数点【数论】

    正题 题目链接:https://ac.nowcoder.com/acm/contest/11179/E 题目大意 定义\(f(x)\)表示\(\frac{1}{x}\)的混循环节长度(如果没有循环节就 ...

  10. 国庆出游神器:魔幻黑科技换天造物,让vlog秒变科幻大片!

    摘要:国庆旅游景点人太多,拍出来的照片全是人人人.车车车,该怎么办?不妨试试这个黑科技,让你的出游vlog秒变科幻大片. 本文分享自华为云社区<国庆出游神器,魔幻黑科技换天造物,让vlog秒变科 ...