BZOJ2327: [HNOI2011]勾股定理

Description


题解Here!

这是一道神题。。。

我一开始把题目看错了,我以为是在$n$根木棒中选两个$i,j$满足$gcd(i,j)==1$,并且存在$k$使得$i^2+j^2==k^2$。

我说这不是网络流的沙茶题嘛?

然后数据范围$n<=10^6$。。。

怎么这么大?就算建图建完了,$Dinic$好像也会$TLE$,预流推进可能都会$TLE$。。。

然后回头看题——$MD$,我就是个$zz$。。。

选取若干个。。。

于是这题就比较好做了。

这里有一篇$YDC$巨佬的博客讲的比我好:链接。

首先要预处理出$10^6$以内的勾股数对。

根据初中的经验,我们有:$$(m^2-n^2)^2+(2mn)^2=(m^2+n^2)^2$$

这个应该都会证吧,全部拆开就好了。

于是一对互质勾股数$(a,b)$与一对$(i,j)$应满足$$a=j^2-i^2,b=2\times i\times j,c=j^2+i^2,gcd(i,j)==1,i<j,\text{i和j不同奇偶}$$

我们枚举$i,j$,由于$i\times j<=\frac{10000000}{2}$,并且$gcd$的复杂度上限是$\log_2n$,一般不会达到,所以就是$500000\times \log_2 500000<500000\times 20=10^7$的复杂度。

我们对于互质勾股数$(a,b)$,在$a,b$间连边。

我们假设他们构成了一片森林,那么题目变成在森林中选点且互不相邻了,跟P1352 没有上司的舞会很像,经典树形$DP$。

但是自从我发现这个不是基环无向树就不想做了。

设$dp[i][0]$表示在$i$这棵子树上不选$i$的方案数,$dp[i][1]$表示在$i$这颗子树上选$i$的方案数。

状态转移长这样:
$$dp[i][0]=(dp[v_1][0]+F[v_1][1])\times (dp[v_2][0]+dp[v_2][1])\times ...$$
$$dp[i][1]=(2^{num[i]}-1)\times dp[v_1][0]\times dp[v_2][0]\times ...$$

$num[i]$表示$i$出现了几次。

我们发现我们建的图将构成一片森林。

假设森林里每颗树的根是$rt_1,rt_2,...rt_k$,那么答案就是:
$$(dp[rt_1][0]+dp[rt_1][1])\times(dp[rt_2][0]+dp[rt_2][1])\times ...\text{之后再减1,即去掉空集}$$

$BUT$!这么做是$30$分。

我当时懵的一批啊。。。感觉这方法行得通吗???

然后我发现一个智障一样的问题——图并不一定是树,可能有环。。。

靠!这个坑。。。

接下来就开始乱搞了。。。

对于一条回边$(u,v)$,就像$tarjan$求强连通中的$dfn[v]<dfn[u]$一样,我们把$u,v$标记一下加入点集$stack$,把这条边删掉。

之后$2^{|stack|}$枚举每个点的选择情况,在合法的情况下套用树形$DP$。

这个时候由于是同一棵树,所以用加法原理而不是乘法原理,即每次统计的答案用个变量累加,最后乘以这个变量。

这题就做完了

吗?

没有!

但是因为数据水的原因,出题人强行把$NP$的题出成了普通题。。。

所以这题就当过了吧。。。

HN的出题人真是不负责任。。。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#define MAXN 1000010
#define MOD 1000000007
using namespace std;
vector<int> stack;
int n,c=1,d=1,T;
int head[MAXN],deep[MAXN],vis[MAXN],num[MAXN];
long long bit[MAXN],dp[MAXN][2];
bool used[MAXN],choose[MAXN];
struct Edge{int next,to;
}a[MAXN];
inline int read(){int date=0,w=1;char c=0;while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}return date*w;
}
inline long long sqr(long long x){return x*x;}
int gcd(int x,int y){if(!y)return x;return gcd(y,x%y);
}
inline void add(int x,int y){a[c].to=y;a[c].next=head[x];head[x]=c++;a[c].to=x;a[c].next=head[y];head[y]=c++;
}
void build(){int m=MAXN-10;for(int i=1;i<=m/2;i++)for(int j=i+1;j<=m/2/i&&sqr(j)-sqr(i)<=m;j++)if(((i&1)!=(j&1))&&gcd(i,j)==1)add(2LL*i*j,sqr(j)-sqr(i));bit[0]=1;for(int i=1;i<=m;i++)bit[i]=(bit[i-1]<<1)%MOD;
}
inline void insert(int x){if(!used[x]){used[x]=true;stack.push_back(x);}
}
bool check(int u,int f){vis[u]=T;for(int i=head[u];i;i=a[i].next){int v=a[i].to;if(v==f||!num[v])continue;if(choose[u]&&choose[v])return false;if(vis[v]!=T)if(!check(v,u))return false;}return true;
}
void dfs1(int x,int f){deep[x]=d++;for(int i=head[x];i;i=a[i].next){int v=a[i].to;if(!num[v]||v==f)continue;if(!deep[v])dfs1(v,x);else if(deep[v]<deep[x]){insert(x);insert(v);}}
}
void dfs2(int x,int f){vis[x]=T;dp[x][0]=1;dp[x][1]=(bit[num[x]]-1+MOD)%MOD;if(used[x]){if(choose[x])dp[x][0]=0;else dp[x][1]=0;}for(int i=head[x];i;i=a[i].next){int v=a[i].to;if(v==f||!num[v]||vis[v]==T)continue;if(vis[v]!=T)dfs2(v,x);dp[x][0]=dp[x][0]*(dp[v][0]+dp[v][1])%MOD;dp[x][1]=dp[x][1]*dp[v][0]%MOD;}
}
void dfs3(int i,int m,int x,long long &ans){if(i==m){T++;if(check(x,-1)){T++;dfs2(x,-1);ans=(ans+dp[x][0]+dp[x][1])%MOD;}return;}choose[stack[i]]=false;dfs3(i+1,m,x,ans);choose[stack[i]]=true;dfs3(i+1,m,x,ans);
}
long long solve(int x){stack.clear();dfs1(x,-1);int m=stack.size();long long ans=0;dfs3(0,m,x,ans);return ans;
}
void work(){long long ans=1;for(int i=1;i<=MAXN-10;i++)if(num[i]&&!deep[i])ans=ans*solve(i)%MOD;printf("%lld\n",(ans-1+MOD)%MOD);
}
void init(){n=read();for(int i=1;i<=n;i++){int x=read();num[x]++;}
}
int main(){build();init();work();return 0;
}

转载于:https://www.cnblogs.com/Yangrui-Blog/p/9488125.html

BZOJ2327: [HNOI2011]勾股定理相关推荐

  1. 【bzoj2327】[HNOI2011]勾股定理

    题目链接 Description 题解 膜拜ydc大神的题解. 对于1000000以内的互质勾股数两两建边. 即在这个森林中选择不相邻的点,可以树形DP解决. 但是并不是树,可能有回边. 那么暴力枚举 ...

  2. 杂题题解(康复训练)

    目录 关于10.05标准化测试: T1: 题目描述: 题解: T2: 题目描述: 前置知识及证明(话说我是真的屑,初中白学了?) 关于10.05标准化测试: T1: 题目描述: [HNOI2011]数 ...

  3. C# WPF动点任意移动气泡画法(解决方案使用到数学勾股定理、正弦定理、向量知识)。...

    原文:C# WPF动点任意移动气泡画法(解决方案使用到数学勾股定理.正弦定理.向量知识). 许久没写博客了,最近在研究WPF下气泡的画法,研发过程还是比较艰辛的(主要是复习了高中的数学知识,MMP全忘 ...

  4. BZOJ 2337: [HNOI2011]XOR和路径( 高斯消元 )

    一位一位考虑异或结果, f(x)表示x->n异或值为1的概率, 列出式子然后高斯消元就行了 --------------------------------------------------- ...

  5. python勾股定理_Python学习第128课——在Python中实现醉汉随机游走

    [每天几分钟,从零入门python编程的世界!] 这节我们在2D平面内实现随机游走.我们先把原理搞清楚,用代码实现这个原理. 原理分析: 我们想像在2D平面内有一个x轴和y轴组成的坐标系,有一个人他是 ...

  6. bzoj2339[HNOI2011]卡农 dp+容斥

    2339: [HNOI2011]卡农 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 842  Solved: 510 [Submit][Status ...

  7. 定理在数学中的简写形式_西方把勾股定理叫毕达哥拉斯定理,我们的教材上是不是该改改名?...

    勾股定理是我们在平面几何中学过的最基本的一个定理了,但是相信很多人都听说过,在西方国家,勾股定理并不叫勾股定理,而是叫做"毕达哥拉斯定理"(Pythagorean Theorem) ...

  8. BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )

    BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...

  9. acf滞后数必须为正整数。_【知识点】“勾股定理”的必考点,必须掌握!

    于茫茫书海中,为你寻找更适合自己成长的有效资源和那些锲入心灵的文字.与高人交心,轻松学习,把时间留给更重要的人更重要的事. 第一.初中学习内容更多,更系统,更难. 小学需要主要是语文.数学.英语.科学 ...

  10. 2014/School_C_C++_A/5/勾股定理

    勾股定理,西方称为毕达哥拉斯定理,它所对应的三角形现在称为:直角三角形. 已知直角三角形的斜边是某个整数,并且要求另外两条边也必须是整数. 求满足这个条件的不同直角三角形的个数. [数据格式] 输入一 ...

最新文章

  1. 《微型计算机2014年》更新至12月下
  2. python读文件代码-Python读取表格类型文件代码实例
  3. 自顶向下 与自底向上解决01 背包问题
  4. 的union_C语言“隐秘的角落”——union没那么简单
  5. 安卓编程坐标系的一个问题
  6. linux下Bash编程until语句及格式化硬盘分区等编写脚本(十)
  7. CentOS 7 gedit编辑器中文乱码解决方法
  8. JNDI 是什么,怎么理解
  9. 银行测试(2)-专有名词
  10. 新计算机 安装win2000,虚拟机安装Windows 2000超详细教程
  11. 地对地导弹地对地导弹地对地导弹
  12. HOJ 2786 Convert Kilometers to Miles
  13. JDK源代码以及200多部软件著作中出现的以连字符构造的1011个合成词
  14. pyqt5 和 pySinde2 动态加载 QT Designer
  15. 预警信息发布程序设计
  16. archlinux 解决蓝牙无法连接问题
  17. itms-services php,APP发布系统 ipa文件上传和下载 itms-service协议
  18. 新公司(企业)在各银行开基本户所需资料、流程及费用
  19. 虚幻引擎中的反射(译)
  20. java 开源网盘_现在的开源网盘还有哪些推荐?

热门文章

  1. 8月| R社区原创作者免费赠书
  2. 用R语言实现深度学习情感分析
  3. R语言数据可视化---交互式图表recharts包
  4. mysql开启slowquery_log_MySQL slow_query_log慢查询日志配置详解
  5. CSS 常见的8种选择器 和 文本溢出问题
  6. Maven web项目(简单的表单提交) 搭建(eclipse)
  7. HDU 4143 A Simple Problem 分解因式
  8. d3_3 ATM模拟系统
  9. Greenplum技术浅析
  10. 宁愿自己多做点,也不愿意客户多做点