Description

羽月最近发现,她发动能力的过程是这样的:

构建一个 V 个点的有向图 G,初始为没有任何边,接下来羽月在脑中构建出一个长度为 E 的边的序列,序列中元素两两不同,然后羽月将这些边依次加入图中,每次加入之后计算当前图的强连通分量个数并记下来,最后得到一个长度为E 的序列,这个序列就是能力的效果。

注意到,可能存在边的序列不同而能力效果相同的情况,所以羽月想请你帮她计算能发动的不同能力个数,答案对 998244353 取模。你需要对于1<=E<=V*(V-1)的所有 E 计算答案。

Data Constraint

对于 10%的数据,1<=V<=5

对于 30%的数据,1<=V<=20

对于 60%的数据,1<=V<=50

对于 100%的数据,1<=V<=100

solution

全场切的题目咱连题目都看不懂对咱来说已经是日常了

题解觉得这题太水于是只有一句话于是咱只好对着一份代码理解了半天

考虑一个策略,我们维护一条链\(1\)到\(i\),如果连的下一条边需要不减少强连通分量个数,那么就连上\((i,i+1)\),如果需要减少强连通分量个数,那么就在链上选一个点向前连边

不难发现,每一种强连通分量序列的情况,都可以通过这种策略来表示

考虑\(dp\),设\(dp_{i,j,k}\)表示连了\(i\)条边,上面有\(j\)个点已经在强连通分量里了,对于链维护到了\(1\)到\(k\),那么枚举下一条边,考虑它是未增加强连通分量个数或者减少的强连通分量个数,转移即可

还有一种尴尬的情况就是点全都连完了,但我们还需要使强连通分量个数不变,这种时候往前连一条没用的边就行了

顺带注意,我们在连环边和无用边的时候可能会有边爆掉的情况,设链上有\(n\)个点,有\(j\)个在环里(即强连通分量),那么链上的每个点可以向后面的所有点连边,环上的每个点可以向前面的所有点连边,就算全部连满,边数也不能超过\(\frac{n(n+1)+j(j+1)}{2}\)

然后就没有然后了,理论上来说时间复杂度\(O(v^5)\),只要用刷表法,判断一下当前状态是否可行就行了

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
inline int max(const R int &x,const R int &y){return x>y?x:y;}
inline int min(const R int &x,const R int &y){return x<y?x:y;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res=1,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int K=-1,Z=0;
inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
void print(R int x){
if(K>1<<20)Ot();if(x<0)x=-x,sr[++K]='-';
while(z[++Z]=x%10+48,x/=10);
while(sr[++K]=z[Z],--Z);sr[++K]=' ';
}
const int N=105,P=998244353;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
int dp[N*N][N][N];
int n,res;
int main(){
// freopen("testdata.in","r",stdin);
freopen("counting.in","r",stdin);
freopen("counting.out","w",stdout);
scanf("%d",&n);
dp[0][1][1]=1;
fp(i,0,n*(n-1)-1)fp(j,1,min(n,i+1))fp(k,j,min(n,i+1))
if(dp[i][j][k]){
if(i<=k+j-2&&k<n)dp[i+1][j][k+1]=add(dp[i+1][j][k+1],dp[i][j][k]);
else if(k*(k-1)+j*(j-1)>=(i+1<<1))dp[i+1][j][k]=add(dp[i+1][j][k],dp[i][j][k]);
fp(l,1,k-j)
if(k*(k-1)+(j+l)*(j+l-1)>=(i+1<<1))dp[i+1][j+l][k]=add(dp[i+1][j+l][k],dp[i][j][k]);
}
fp(i,1,n*(n-1)){
res=0;
fp(j,1,min(n,i+1))fp(k,j,min(n,i+1))res=add(res,dp[i][j][k]);
print(res);
}
return Ot(),0;
}

jzoj6009. 【THUWC2019模拟2019.1.18】Counting (dp)的更多相关文章

  1. jzoj6008. 【THUWC2019模拟2019.1.18】Sequence (矩阵加速)

    题面 茉优最近研究发现,一个人的想愿能力可以认为是字符串S的一个子串S[l,r],而连接值可以认为是这个子串的本质不同子序列个数.现在她想验证她的结论是否正确,于是她给了你Q个询问,希望你帮她来计算, ...

  2. 6362. 【NOIP2019模拟2019.9.18】数星星

    题目描述 题解 一种好想/好写/跑得比**记者还快的做法: 对所有询问排序,按照R递增的顺序来处理 维护每个点最后一次被覆盖的时间,显然当前右端点为R时的答案为所有时间≥L的点的权值之和 LCT随便覆 ...

  3. 6361. 【NOIP2019模拟2019.9.18】鲳数

    题目 题目大意 给你一个区间\([l,r]\),求这个区间内每个整数的十进制上从高位到低位的逆序对个数之和. 思考历程 一开始就知道这是个数位DP-- 结果一直都没有调出来,心态崩了-- 正解 先讲讲 ...

  4. jzoj6003. 【THUWC2019模拟2019.1.16】Square (乱搞)

    题面 题解 不难发现,如果一行最后被染色,那么这行的颜色肯定一样,如果倒数第二个被染色,那么除了被最后一个染色的覆盖的那一部分剩下的颜色肯定一样 于是题目可以转化为每一次删去一行或一列颜色相同的,问最 ...

  5. 2019.3.18考试&2019.3.19考试&2019.3.21考试

    2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 哇说的简单,码了将近一下午终于码出来了 感觉自己码力/写题策略太糟糕了,先是搞了一个细节太多的写法最后不得不弃疗了,然后第二 ...

  6. NOIP模拟 17.8.18

    NOIP模拟17.8.18 A.小菜一碟的背包[题目描述]Blice和阿强巴是好朋友但萌萌哒Blice不擅长数学,所以阿强巴给了她一些奶牛做练习阿强巴有 n头奶牛,每头奶牛每天可以产一定量的奶,同时也 ...

  7. NOIP模拟测试17&18

    NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...

  8. 【NOI2019模拟2019.6.27】B (生成函数+整数划分dp|多项式exp)

    Description: \(1<=n,k<=1e5,mod~1e9+7\) 题解: 考虑最经典的排列dp,每次插入第\(i\)大的数,那么可以增加的逆序对个数是\(0-i-1\). 不难 ...

  9. [JZOJ6075]【GDOI2019模拟2019.3.20】桥【DP】【线段树】

    Description N,M<=100000,S,T<=1e9 Solution 首先可以感受一下,我们把街道看成一行,那么只有给出的2n个点的纵坐标是有用的,于是我们可以将坐标离散化至 ...

随机推荐

  1. mysql服务突然不能启动

    mysql之前一直用的好好的,今天突然不能启动.前几天改过my.ini文件,在[mysqld]下添加了default-character-set=utf8.查看日志发现是添加的那句话的错误,删除.并且 ...

  2. JDBC超时原理与设置

    抄录自网上,因为担心以后找不到,因此抄录之.感谢分享的大神! 英文原版:http://www.cubrid.org/blog/dev-platform/understanding-jdbc-inter ...

  3. Linux桥接网络配置

    在虚拟机网络配置中,选择桥接的方式.然后进入linux进行设置. 编辑 vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPR ...

  4. 开始使用Python

    1. 开始使用Python 1.1 print使用str()函数显示对象,而交互式解释器调用repr()函数来显示对象. 1.2 在解释器中_表示最后一个表达式的值. 1.3 >>用来重定 ...

  5. latex 技巧汇总

    最近打算详细的学习一下latex,所以在学习的过程中遇到了一些问题.随时出问题,随时记录更新. 我是萌萌的Latex, x_0. 再写具体的技巧之前,先说一个关于打公式的小技巧.有时候你不知道怎么设置 ...

  6. matlab之mean()函数

    mean(A,1):沿着第一维(列)求平均值: mean(A,2):沿着第二维(行)求平均值: 举例: Z=[1 2 3;4 5 6]; >> mean(Z,1) ans = 2.5000 ...

  7. css3线性渐变兼容

    火狐浏览器: background:-moz-linear-gradient(top, red, rgba(0, 0, 255, 0.5)); 谷歌: .l6{background: -webkit- ...

  8. BZOJ3991:寻宝游戏 (LCA+dfs序+树链求并+set)

    小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路上行走 ...

  9. ACM学习历程——HDU1331 Function Run Fun(锻炼多维dp的打表)

    Description We all love recursion! Don't we?        Consider a three-parameter recursive function w( ...

  10. uC/OS-II源码分析(三)

    首先来了解下实时系统的基本概念: 1) 临界区,共享资源,任务(类似于进程),任务切换,任务调度,可剥夺型内核,可重入函数,动态优先级调度, 2) 如何处理优先级反转问题.这个问题描述如下:有三个任务 ...