Luogu5288

注意:n边形里共有n-3条边

最优步数=不与n相连的边数,关键是方案数.

按照处理顺序可以转化为树形结构即二叉树森林,转移方案数用组合数即可

关键是快速处理修改.

1.最优解减少一步,即删掉某棵二叉树的根,合并它的两个儿子.

2.相当于在splay中把它rotate一下,而且不知道为什么它还一定是左儿子

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<vector>
  6. #include<map>
  7. #include<cassert>
  8. #define debug(...) fprintf(stderr,__VA_ARGS__)
  9. #define Debug(x) cout<<#x<<"="<<x<<endl
  10. using namespace std;
  11. typedef long long LL;
  12. typedef pair<int,int> pii;
  13. const int INF=1e9+7;
  14. inline LL read(){
  15. register LL x=0,f=1;register char c=getchar();
  16. while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
  17. while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
  18. return f*x;
  19. }
  20. const int N=100005;
  21. const int mod=1e9+7;
  22. int size[N],ls[N],rs[N],fa[N],fac[N],ifac[N],inv[N];
  23. int W,n,m,sum,ans=1,Ecnt;
  24. vector <int> E[N];
  25. map <pii,int> M;
  26. inline int add(int x,int y){x+=y;return x>=mod?x-mod:x;}
  27. inline int mul(LL x,int y){x*=y;return x>=mod?x%mod:x;}
  28. inline int cal(int x,int y){return mul(fac[x+y],mul(ifac[x],ifac[y]));}
  29. inline int ical(int x,int y){return mul(ifac[x+y],mul(fac[x],fac[y]));}
  30. inline void dfs(int &x,int l,int r,int pre){
  31. if(l+1==r) return;
  32. x=++Ecnt;///
  33. M[pii(l,r)]=x,fa[x]=pre;
  34. int mid=*upper_bound(E[r].begin(),E[r].end(),l);
  35. dfs(ls[x],l,mid,x);
  36. dfs(rs[x],mid,r,x);
  37. size[x]=size[ls[x]]+size[rs[x]]+1;
  38. ans=mul(ans,cal(size[ls[x]],size[rs[x]]));
  39. }
  40. inline void answer(int x,int y){
  41. if(W==0) printf("%d\n",x);
  42. else printf("%d %d\n",x,y);
  43. }
  44. int main(){
  45. W=read(),n=read();
  46. inv[0]=inv[1]=fac[0]=fac[1]=ifac[0]=ifac[1]=1;
  47. for(int i=2;i<=n;i++) inv[i]=mul(inv[mod%i],mod-mod/i);///
  48. for(int i=2;i<=n;i++) fac[i]=mul(fac[i-1],i),ifac[i]=mul(ifac[i-1],inv[i]);
  49. for(int i=1;i<=n-3;i++){
  50. int x=read(),y=read();
  51. E[x].push_back(y);E[y].push_back(x);
  52. }
  53. for(int i=1;i<n;i++) E[i].push_back(i+1),E[i+1].push_back(i);
  54. E[1].push_back(n),E[n].push_back(1);
  55. for(int i=1;i<=n;i++) sort(E[i].begin(),E[i].end());
  56. for(int i=0;i<(E[n].size()-1);i++){
  57. int tmp=0;
  58. dfs(tmp,E[n][i],E[n][i+1],0);
  59. ans=mul(ans,cal(sum,size[tmp]));
  60. sum+=size[tmp];
  61. }
  62. answer(sum,ans);
  63. m=read();
  64. for(int i=1;i<=m;i++){
  65. int a=read(),b=read(),x=M[pii(a,b)];
  66. int qans=ans,qsum=sum;//-(a==n||b==n);
  67. if(!fa[x]){
  68. //assert(qsum==sum-1);
  69. qsum--;
  70. qans=mul(qans,ical(size[ls[x]],size[rs[x]]));
  71. qans=mul(qans,ical(sum-size[x],size[x]));
  72. qans=mul(qans,cal(sum-size[x],size[ls[x]]));
  73. qans=mul(qans,cal(sum-size[x]+size[ls[x]],size[rs[x]]));
  74. }
  75. else{
  76. int y=fa[x],k=(rs[y]==x);
  77. qans=mul(qans,ical(size[ls[x]],size[rs[x]]));
  78. qans=mul(qans,ical(size[ls[y]],size[rs[y]]));
  79. if(k==0){
  80. qans=mul(qans,cal(size[rs[x]],size[rs[y]]));
  81. qans=mul(qans,cal(size[ls[x]],size[rs[x]]+size[rs[y]]+1));
  82. }
  83. if(k==1){
  84. assert(false);
  85. qans=mul(qans,cal(size[ls[y]],size[ls[x]]));
  86. qans=mul(qans,cal(size[rs[x]],size[ls[y]]+size[ls[x]]+1));
  87. }
  88. }
  89. answer(qsum,qans);
  90. }
  91. }

[HNOI2019]多边形的更多相关文章

  1. 【BZOJ5491】[HNOI2019]多边形(模拟,组合计数)

    [HNOI2019]多边形(模拟,组合计数) 题面 洛谷 题解 突然特别想骂人,本来我考场现切了的,结果WA了几个点,刚刚拿代码一看有个地方忘记取模了. 首先发现终止态一定是所有点都向\(n\)连边( ...

  2. HNOI2019 多边形 polygon

    HNOI2019 多边形 polygon https://www.luogu.org/problemnew/show/P5288 这题镪啊... 首先堆结论: 显然终止状态一定是所有边都连向n了 根据 ...

  3. luogu P5288 [HNOI2019]多边形

    传送门 这是什么神仙操作... 首先要注意一些性质.首先每一个\((x,n)\)的边可以把当前多边形分成两半,这两半的操作是独立的.然后对于某一个没有\((x,n)\)的边的多边形,最优操作是唯一的. ...

  4. 【洛谷5288】[HNOI2019] 多边形(二叉树模型)

    点此看题面 大致题意: 给你一个多边形,用若干不重合.不相交的线段将其划分为若干三角形区域,并定义旋转操作\((a,c)\)为选定\(4\)个点\(a,b,c,d\)满足\(a<b<c&l ...

  5. [HNOI2019]多边形[二叉树建模、组合计数]

    题意 题目链接 分析 不难发现终态一定是 \([2,n-2]\) 中的每个点都与 \(n\) 连边. 关于凸多边形的划分问题,可以将它看作一棵二叉树:每个树点可以看做点可以看做边. 本题中看做点来处理 ...

  6. 【题解】Luogu P5288 [HNOI2019]多边形

    原题传送门 HN的题目就是毒瘤 我们有以下猜想: 1.最后所有的线都连到了n号点上 2.最小步数应该为n-3-已经连到n号点的线段数量 本来有些边\((a_i,n)\)会将整个图分割成很多个区间.对于 ...

  7. ZJOI2019Day2余姚中学游记(4.23~4.26)

    前言 \(Day2\),又是一场噩梦. 前段时间去做了挺多十二省联考和\(HNOI2019\)的题目,还订正掉了\(Day1\)的\(T1\)和\(T2\)(\(T3\)动态\(DP\)完全不想订正啊 ...

  8. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  9. 【loj3056】【hnoi2019】多边形

    题目 描述 ​ 给出一个 \(n\) 个点的多边形初始的三角剖分: ​ 一次合法的旋转定义为 \((a,b,c,d)\) ,满足 \(a<b<c<d\) : ​ 并且存在边\((a, ...

随机推荐

  1. 二分图 and code1170 双栈排序

    6.6二分图 二分图是这样一个图: 有两顶点集且图中每条边的的两个顶点分别位于两个顶点集中,每个顶点集中没有边直接相连接. 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶 ...

  2. 马婕 2014MBA专硕考试 报刊选读 6(转)

    http://blog.sina.com.cn/s/blog_3e66af4601016udh.html Protecting the weakest保护最弱势群体The recession may ...

  3. 如何用word文档在博客里发表文章

    目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...

  4. PHP(二)变量和常量

  5. swift po 实现动态按钮2

    // //  ButtonViewController.swift //  PopInstall // //  Created by su on 15/12/11. //  Copyright © 2 ...

  6. 20155335俞昆《java程序设计》第6周总结

    20155335    <Java程序设计>第6周学习总结 ##  教材学习内容总结 首先,我们需要了解输入和输出的关系,我想,这不同于c语言中的输入和输出,我们首先明白,Java中以串流 ...

  7. 咏南 DATASNAP LINUX中间件

    咏南 DATASNAP LINUX中间件,一套源码,同时支持WINDOWS和LINUX操作系统. 基于DELPHI 10.2 TOKYO开发 使用FIREDAC数据库引擎,支持MYSQL,MSSQL, ...

  8. 自我简介与Github的注册和使用

    我叫陈鑫,学号1413042059,来自网络工程142班.喜欢打乒乓球,玩策略类游戏,团队竞技.                                                     ...

  9. nancyfx中的静态内容文件夹

    原文件 DefaultStaticContentsConventions.cs 可以根据需要自定调整,在代码里改的好处是通用.如果通过在webconfig里设置的话,在非iis环境下,可能会有问题. ...

  10. python经典书记必读:Python编程快速上手 让繁琐工作自动化

    所属网站分类: 资源下载 > python电子书 作者:熊猫烧香 链接:http://www.pythonheidong.com/blog/article/69/ 来源:python黑洞网,专注 ...