【GDOI2018模拟7.7】暴力大神hxx 树形dp
来源:互联网 发布:淘宝reebonz海外旗舰店 编辑:程序博客网 时间:2024/06/05 14:26
题意:给你n个嵌套for语句,然后从第二个开始每一个循环的起点或者是终点是变量,问你会循环多少次。
这是一道好题。
手玩一下可以很容易发现,上下之间有可以递推的关系,但是直接递推会炸,所以需要dp。
假设语句是这样的:
for i 1 100
for j i 100
for k j 100
我们可以手玩一下发现:
只有一条语句:
1-100
两条语句:
(1-100,2-100,3-100…….100-100) 相邻之间差为1.
三条语句(这里对齐一下让大家更好理解):(1-100,2-100,3-100.......100-100) (2-100,3-100.......100-100) (3-100.......100-100) .... 注意从这里开始差变得不规则了,我把这种不规则的差称之为量级。 可以发现的是,量级的大小明显和嵌套语句的个数有一个公式可以互相转换,那么用相关的数学知识应该是可以推出的(我不会QAQ),但是对于一个OIER,做到这一步就够了。
我们并不需要直接计算出量级,只要无脑往上用乘法原理乘乘乘就好了。
可以发现,第n条语句和第n-1条直接相关,可以通过他推出来,但是他也和第n-2…1条语句间接有关,所以,可以联想到树形dp(比较关键的一步,其实挺好想,模型很明显了)
然后,设f[x][i]以x为根的子树的答案,或者说:把变量x取值为i时的计算结果
那么根据乘法原理直接把所有子树乘起来就好了,但是还是会T,用前缀和优化一下(第二个比较关键的地方),具体看代码。
转化模型和处理方法都十分经典。
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--);using namespace std;typedef long long ll;const int mo=12015858;const int N=1e5+5;char x[N],y[N],n;int l[N],r[N],f[27][N];int tot;bool vis[N];int head[N],go[N],next[N],val[N];inline void add(int x,int y){ go[++tot]=y; next[tot]=head[x]; head[x]=tot;}inline void dfs(int x){ for(int i=head[x];i;i=next[i]) { int v=go[i]; dfs(v); } fo(i,1,100000) { f[x][i]=1; for(int j=head[x];j;j=next[j]) { int v=go[j]; if (!l[v]&&i>r[v]||!r[v]&&i<l[v]) { f[x][i]=0; break; } if (!r[v])f[x][i]=1ll*f[x][i]*(f[v][i]-f[v][l[v]-1])%mo; else f[x][i]=1ll*f[x][i]*(f[v][r[v]]-f[v][i-1])%mo; } f[x][i]=(f[x][i]+mo)%mo; } fo(i,1,100000)f[x][i]=(f[x][i]+f[x][i-1])%mo;}int main(){ scanf("%d",&n); fo(i,1,n) { char ch[7]; scanf("%s",ch); int len=strlen(ch); if (ch[0]<='z'&&ch[0]>='a') { add(ch[0]-'a'+1,i); vis[i]=1; } else fo(j,0,len-1)l[i]=l[i]*10+ch[j]-'0'; scanf("%s",ch); len=strlen(ch); if (ch[0]<='z'&&ch[0]>='a') { add(ch[0]-'a'+1,i); vis[i]=1; } else fo(j,0,len-1)r[i]=r[i]*10+ch[j]-'0'; } ll ans=1; fo(i,1,n)if (!vis[i]) { dfs(i); ans=ans*1ll*(f[i][r[i]]-f[i][l[i]-1])%mo; } printf("%lld\n",(ans+mo)%mo);}
阅读全文
0 0
- 【GDOI2018模拟7.7】暴力大神hxx 树形dp
- JZOJ 5207【GDOI2018模拟7.7】暴力大神hxx
- 暴力大神hxx 树形dp
- 【GDOI2018模拟7.12】B 矩阵乘法+dp
- jzoj5220 【GDOI2018模拟7.10】C (双序列dp)
- JZOJ5220. 【GDOI2018模拟7.10】C(2017.8DP&贪心专题)
- 【JZOJ5262】【GDOI2018模拟8.12】树(DP,性质题)
- 【GDOI2018模拟7.7】寻找天哥
- hdu 5469 Antonidas 树形dp+暴力 ★
- [树形DP 暴力] BZOJ 3696 化合物
- NOIP模拟 探险 【树形dp】
- 【GDOI2018模拟7.6】吃干饭
- 【GDOI2018模拟7.9】期末考试
- 【GDOI2018模拟7.8】质数
- 【GDOI2018模拟7.8】矩阵
- 【GDOI2018模拟7.10】B
- 【GDOI2018模拟7.10】C
- 【GDOI2018模拟7.10】B
- Activity页面之间的数据传递
- 博客里《DSAA》相关文章的代码
- ArcPy批量掩膜裁剪栅格/图像
- SharedPreferences的简单用法
- Day21- JDBC事务(JDBC加强)
- 【GDOI2018模拟7.7】暴力大神hxx 树形dp
- javascript里的"类"
- OpenCV中CV_Assert函数和C++中assert()函数
- CSDN日报20170706——《屌丝程序员的逆袭之旅》
- 你是否真的了解编程语言?
- 类和对象基础
- MAKEINTRESOURCE的作用
- One-Hot encoder独热编码
- phpstorm快捷键