博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 6044 - Limited Permutation | 2017 Multi-University Training Contest 1
阅读量:5734 次
发布时间:2019-06-18

本文共 4533 字,大约阅读时间需要 15 分钟。

研究一下建树 :

/*HDU 6044 - Limited Permutation [ 读入优化,笛卡尔树 ]  |  2017 Multi-University Training Contest 1题意:	给出两组序列 l[i], r[i], 代表以 p[i] 为最小值所在的区间的边界	问 满足这些条件的序列 p 的个数分析:	必定能找到一个p[i] 使得 l[i] == 1, r[i] == n ,其将数组分成两块[1, i-1], [i+1, n]	以之为根节点,将区间为[1, i-1] 和 [i+1, n] 的节点作为左右儿子,再在每一块上递归地进行划分,则构成一棵笛卡尔树	能构成的笛卡尔树的形状是唯一的,若不能构成,则 ans = 0	若能构成,则 以i为根的子树的方案数 f(i) = C(size_l+size_r, size_l) * f(l) * f(r)	数据很多用fread读入*/#include 
using namespace std;#define LL long longconst int N = 1e6+5;const LL MOD = 1e9+7;namespace IO { const int MX = 4e7; //1e7 占用内存 11000kb char buf[MX]; int c, sz; void begin() { c = 0; sz = fread(buf, 1, MX, stdin);//一次性全部读入 } inline bool read(int &t) { while (c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++; if (c >= sz) return false;//若读完整个缓冲块则退出 bool flag = 0; if(buf[c] == '-') flag = 1, c++; for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0'; if(flag) t = -t; return true; }}namespace COMB { int F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘 void init(){ inv[1] = 1; for(int i = 2; i < N; i ++){ inv[i] = (MOD - MOD / i) * 1LL * inv[MOD % i] % MOD; } F[0] = Finv[0] = 1; for(int i = 1; i < N; i ++){ F[i] = F[i-1] * 1LL * i % MOD; Finv[i] = Finv[i-1] * 1LL * inv[i] % MOD; } } int comb(int n, int m){//comb(n, m)就是C(n, m) if(m < 0 || m > n) return 0; return F[n] * 1LL * Finv[n - m] % MOD * Finv[m] % MOD; }}struct Node{ int f, l, r;}T[N];int l[N], r[N];int n;int q[N], top;inline bool cmp(const int& a,const int& b) { return (r[a] - l[a]) < (r[b] - l[b]);}int Build(){ top = 0; for (int i = 1; i <= n; i++) { int k = top; while (k && cmp(q[k-1], i)) --k; if (k != 0) { T[i].f = q[k-1]; T[q[k-1]].r = i; } if (k != top) { T[q[k]].f = i; T[i].l = q[k]; } q[k++] = i; top = k; } return q[0];}bool flag;LL ans;LL dfs(int x, int L, int R){ if (!x) return 1; if (!flag) return 0; if (l[x] != L || r[x] != R) return 0; LL res = COMB::comb(R-L, R-x); res = res * dfs(T[x].l, L, x-1) % MOD; res = res * dfs(T[x].r, x+1, R) % MOD; if (res == 0) flag = 0; return res;}int main(){ COMB::init(); IO::begin(); for (int tt = 1; IO::read(n); ++tt) { for (int i = 1; i <= n; i++) T[i].l = T[i].r = T[i].f = 0; for (int i = 1; i <= n; i++) IO::read(l[i]); for (int i = 1; i <= n; i++) IO::read(r[i]); int root = Build(); flag = 1; ans = dfs(root, 1, n); printf("Case #%d: %lld\n", tt, ans); }}

  要么直接 map

#include 
using namespace std;#define LL long longconst int N = 1e6+5;const LL MOD = 1e9+7;namespace fastIO { #define BUF_SIZE 100000 //fread -> read bool IOerror = 0; inline char nc() { static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE; if(p1 == pend) { p1 = buf; pend = buf + fread(buf, 1, BUF_SIZE, stdin); if(pend == p1) { IOerror = 1; return -1; } } return *p1++; } inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; } inline void read(int &x) { char ch; while(blank(ch = nc())); if(IOerror) return; for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0'); } #undef BUF_SIZE}namespace COMB { int F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘 void init(){ inv[1] = 1; for(int i = 2; i < N; i ++){ inv[i] = (MOD - MOD / i) * 1LL * inv[MOD % i] % MOD; } F[0] = Finv[0] = 1; for(int i = 1; i < N; i ++){ F[i] = F[i-1] * 1LL * i % MOD; Finv[i] = Finv[i-1] * 1LL * inv[i] % MOD; } } int comb(int n, int m){//comb(n, m)就是C(n, m) if(m < 0 || m > n) return 0; return F[n] * 1LL * Finv[n - m] % MOD * Finv[m] % MOD; }}typedef pair
P;using namespace fastIO;map
mp;int t, n;int l[N], r[N];LL dfs(int l, int r){ if (l > r) return 1; int x = mp[P(l, r)]; if (!x) return 0; LL ans = COMB::comb(r-l, r-x); ans = ans * dfs(l, x-1) % MOD; ans = ans * dfs(x+1, r) % MOD; return ans;}int main(){ COMB::init(); for (int tt = 1; read(n), !IOerror; ++tt) { mp.clear(); for (int i = 1; i <= n; i++) read(l[i]); for (int i = 1; i <= n; i++) read(r[i]); for (int i = 1; i <= n; i++) mp[P(l[i], r[i])] = i; LL ans = dfs(1, n); printf("Case #%d: %lld\n", tt, ans); }}

  

转载于:https://www.cnblogs.com/nicetomeetu/p/7247470.html

你可能感兴趣的文章
我的友情链接
查看>>
关于批处理-1
查看>>
Tomcat部署Web应用方法总结
查看>>
Python3 django2.0 字段加密 解密 AES
查看>>
CCNA实验之:网络地址转换(NAT)实验
查看>>
计算机网络原理笔记-停止等待协议
查看>>
确定当前记录和下一条记录之间相差的天数
查看>>
sql语句返回主键SCOPE_IDENTITY()
查看>>
机器学习开源项目精选TOP30
查看>>
代码分析系列 内存执行过程
查看>>
iOS开发-邮件发送
查看>>
/etc/resolv.conf文件详解
查看>>
【转】VC的MFC中重绘函数的使用总结(整理)
查看>>
JQuery日记_5.13 Sizzle选择器(六)选择器的效率
查看>>
System.gc()与Object.finalize()的区别
查看>>
oracle查看经常使用的系统信息
查看>>
技术工坊|如何利用ERC875协议开发世界杯区块链门票?(北京)
查看>>
Django_4_视图
查看>>
Linux的netstat命令使用
查看>>
shell实例100例《五》
查看>>