传送门

如果不想让next_permutation()自动忽略重复元素,可以在比较函数里加个rk之类的东西使它们不同(next_permutation()不用等于号)

关于第一问:貌似也是一个挺常见的思路

题目要求满足「在位置\(i\)之前比\(val[i]\)大的数严格小于\(k[i]\)个的序列」的个数

考虑这样一种构造方法

把每个二元组按\(val\)降序,\(k\)升序排序,依次加入序列

那么先加入的元素一定大于等于这个元素,不必考虑顺序

所以它能放的位置是前\(k[i]-1\)个空(包括最前面)

而因为不必考虑之前加入的数的顺序,所以消除了后效性

特别注意\(val[i]=val[i+1]\)的情况

\(i+1\)能选择的位置数同样会扩展,而因为前面有\(val\)相同的元素,且这些相同元素的位置此元素也能取到(\(k\)作为第二关键字升序

所以k也相当于扩展了 写了一下午就因为没想明白这个

还有数据好像假了 排列本来不应该考虑完全相同元素的顺序的,但数据考虑进去了

然后考虑如何构造出一个字典序最小的排列

还是考虑之前平衡树那个思路,维护一棵平衡树,每次取最小的,按\(key[i]\)的位置

好吧平衡树写法不太懂,还是说线段树思路吧

考虑维护一个已选集合和一个未选集合,未选集合按字典序排序

每当我们选一个字典序小的元素为已选,因为其\(val\)值可能较大

考虑\(key\)值的实际意义是比这个元素\(val\)值大且先被选为已选的元素最多有多少个

所以每次把所有\(val\)小于当前\(val\)的元素\(key\)值减一

然后如果有元素\(key\)值已经减成1了,那就不能再先选\(val\)比它大的元素了

这时候把它选上就好了

顺带一提,下面的写法看起来好像「把所有\(val\)小于当前\(val\)的元素\(key\)值减一」的时候还减了一部分\(val\)相等的

但实际上排序时\(key\)作为第二关键字升序,\(key\)值相同时还优先选左边的,所以它的左边不会再有等于它的了

Code:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define INF 0x3f3f3f3f
  4. #define N 500010
  5. #define ll long long
  6. #define int long long
  7. char buf[1<<21], *p1=buf, *p2=buf;
  8. #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
  9. inline int read() {
  10. int ans=0, f=1; char c=getchar();
  11. while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
  12. while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
  13. return ans*f;
  14. }
  15. int n;
  16. const ll mod=1e9+7;
  17. struct point{int val, key, rk; inline void build(int v_, int k_) {val=v_; key=k_;}}p[N], bkp[N];
  18. //inline bool operator < (point a, point b) {return a.key==b.key?a.val<b.val:a.key<b.key;}
  19. inline bool operator < (point a, point b) {return a.val==b.val?a.key<b.key:a.val>b.val;}
  20. inline bool cmp1(point a, point b) {return a.val==b.val?a.key<b.key:a.val<b.val;}
  21. inline bool cmp2(point a, point b) {return a.key==b.key?a.val<b.val:a.key<b.key;}
  22. namespace force1{
  23. ll ans;
  24. bool first=1;
  25. void solve() {
  26. sort(p+1, p+n+1);
  27. do {
  28. for (int i=1,cnt; i<=n; ++i) {
  29. cnt=0;
  30. for (int j=1; j<i; ++j)
  31. if (p[i].val<p[j].val) {if (++cnt>=p[i].key) goto jump;}
  32. }
  33. ++ans;
  34. if (first) {
  35. for (int i=1; i<=n; ++i) bkp[i]=p[i];
  36. first=0;
  37. }
  38. jump: ;
  39. } while (next_permutation(p+1, p+n+1));
  40. printf("%lld\n", ans%mod);
  41. for (int i=1; i<=n; ++i) printf("%lld %lld\n", bkp[i].key, bkp[i].val);
  42. exit(0);
  43. }
  44. }
  45. namespace task{
  46. ll ans=1;
  47. bool vis[N];
  48. int tl[N<<2], tr[N<<2], minn[N<<2], mini[N<<2], tag[N<<2];
  49. #define tl(p) tl[p]
  50. #define tr(p) tr[p]
  51. #define minn(p) minn[p]
  52. #define mini(p) mini[p]
  53. #define tag(p) tag[p]
  54. inline void pushup(int p) {
  55. if (minn(p<<1)<=minn(p<<1|1)) minn(p)=minn(p<<1), mini(p)=mini(p<<1);
  56. else minn(p)=minn(p<<1|1), mini(p)=mini(p<<1|1);
  57. }
  58. inline void spread(int p) {
  59. if (!tag(p)) return ;
  60. minn(p<<1)-=tag(p), tag(p<<1)+=tag(p);
  61. minn(p<<1|1)-=tag(p), tag(p<<1|1)+=tag(p);
  62. tag(p)=0;
  63. }
  64. void build(int p2, int l, int r) {
  65. tl(p2)=l; tr(p2)=r;
  66. if (l==r) {minn(p2)=p[l].key; mini(p2)=l; return ;}
  67. int mid=(l+r)>>1;
  68. build(p2<<1, l, mid);
  69. build(p2<<1|1, mid+1, r);
  70. pushup(p2);
  71. }
  72. void upd(int p, int pos) {
  73. if (tl(p)==tr(p)) {minn(p)=INF; vis[tl(p)]=1; return ;}
  74. spread(p);
  75. int mid=(tl(p)+tr(p))>>1;
  76. if (pos<=mid) upd(p<<1, pos);
  77. else upd(p<<1|1, pos);
  78. pushup(p);
  79. }
  80. void upd(int p, int l, int r) {
  81. if (l<=tl(p) && r>=tr(p)) {--minn(p); ++tag(p); return ;}
  82. spread(p);
  83. int mid=(tl(p)+tr(p))>>1;
  84. if (l<=mid) upd(p<<1, l, r);
  85. if (r>mid) upd(p<<1|1, l, r);
  86. pushup(p);
  87. }
  88. void solve() {
  89. sort(p+1, p+n+1);
  90. //for (int i=1; i<=n; ++i) cout<<p[i].val<<' '<<p[i].key<<endl;
  91. int same=0, same2=0;
  92. for (int i=1; i<=n; ++i) {
  93. if (i!=1 && p[i].val==p[i-1].val) ++same;
  94. else same=0;
  95. ans=ans*min(i, p[i].key+same)%mod;
  96. }
  97. printf("%lld\n", ans%mod);
  98. sort(p+1, p+n+1, cmp1);
  99. memcpy(bkp+1, p+1, sizeof(point)*n);
  100. for (int i=1; i<=n; ++i) p[i].rk=i;
  101. build(1, 1, n);
  102. sort(p+1, p+n+1, cmp2);
  103. //for (int i=1; i<=n; ++i) cout<<p[i].key<<' '<<p[i].val<<endl;
  104. for (int i=1,tn,ti,pos=1; i<=n; ++i) {
  105. tn=minn(1), ti=mini(1);
  106. //cout<<"minn: "<<minn(1)<<endl;
  107. //cout<<"vis: "; for (int i=1; i<=n; ++i) cout<<vis[i]<<' '; cout<<endl;
  108. if (minn(1)==1) {
  109. //cout<<"pos1"<<endl;
  110. //cout<<minn(1)<<' '<<mini(1)<<endl;
  111. upd(1, ti);
  112. upd(1, 1, ti);
  113. printf("%lld %lld\n", bkp[ti].key, bkp[ti].val);
  114. }
  115. else {
  116. //cout<<"pos2"<<endl;
  117. while (vis[p[pos].rk]) ++pos; //, cout<<"pos: "<<pos<<endl;
  118. ti=pos;
  119. upd(1, p[pos].rk);
  120. upd(1, 1, p[pos].rk);
  121. printf("%lld %lld\n", p[ti].key, p[ti].val);
  122. }
  123. }
  124. exit(0);
  125. }
  126. }
  127. signed main()
  128. {
  129. n=read();
  130. for (int i=1; i<=n; ++i) p[i].key=read(), p[i].val=read();
  131. //force1::solve();
  132. task::solve();
  133. return 0;
  134. }

题解 block的更多相关文章

  1. 【dp】10-15题解 snake vs block

    snake vs block 题目描述 Tgopknight最近迷上了一款叫做Snake vs Block的游戏,他总觉得他自己玩出的不是最优解,但是他忙于享受游戏的乐趣,只好请你帮忙找出最优解. S ...

  2. HDU5739 Fantasia(点双连通分量 + Block Forest Data Structure)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5739 Description Professor Zhang has an undirect ...

  3. NOIP2013 题解

    转圈游戏 题解:快速幂 #include <cstdio> int n, m, k, x; inline long long QuickPow(int a, int k, int MOD) ...

  4. CF 327D - Block Tower 数学题 DFS 初看很难,想通了就感觉很简单

    D. Block Tower time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  5. Codeforces Round #447 (Div. 2) 题解 【ABCDE】

    BC都被hack的人生,痛苦. 下面是题解的表演时间: A. QAQ "QAQ" is a word to denote an expression of crying. Imag ...

  6. NOIP2013题解

    NOIP2013题解 Day1 转圈游戏 circle 快速幂模板题. #include<iostream> using namespace std; int n,m,k,x; int f ...

  7. Xtreme9.0 - Block Art 线段树

    Block Art 题目连接: https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/block-art Descr ...

  8. 【四校联考】【比赛题解】FJ NOIP 四校联考 2017 Round 7

    此次比赛为厦门一中出题.都是聚劳,不敢恭维. 莫名爆了个0,究其原因,竟然是快读炸了……很狗,很难受. 话不多说,来看看题: [T1] 题意: 样例: PS:1<=h[i]<=100000 ...

  9. CF1083(Round #526 Div. 1) 简要题解

    题目链接 https://codeforces.com/contest/1083 简要题目翻译 题解 A. The Fair Nut and the Best Path 可以忽略掉"任意时刻 ...

随机推荐

  1. sublime最全笔记

    sublime骨架建立 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8&quo ...

  2. C语言:基本数据类型及表示范围

    类型名称 标识符 printf()标志 占据 范围 无符号 unsigned 范围 类型名称 类型标识符    printf标志   占字节数           表示范围              ...

  3. adb 记录ADB执行记录

    自动化测试需要获得当前的activity,来判断处于的页面是否正确: hierarchy view经常连不上真机,无法获得activity,所以直接用 adb命令来查看当前运行的 activity就可 ...

  4. react-router4 介绍

    react-router 的理解: 1) react 的一个插件库2) 专门用来实现一个 SPA 应用3) 基于 react 的项目基本都会用到此库 SPA  的理解: 1) 单页 Web 应用(si ...

  5. java网络编程基础——网络基础

    java网络编程 网络编程基础 1.常用的网络拓扑结构: 星型网络.总线网络.环线网络.树形网络.星型环线网络 2.通信协议的组成 通信协议通常由3部分组成: 语义部分:用于决定通信双方对话类型 语法 ...

  6. IO流之节点流(字符流)和数据流关闭

    ​输入流----Reader 1 public class Reader { 2 public static void main(String[] args) throws Exception { 3 ...

  7. WLS中Linux与Windows间的环境共享

    Reference 更多cmd.exe帮助参考 (cmd_helps)[https://ss64.com/nt/cmd.html] (WSL备份,windows Docker安装)[https://w ...

  8. 【游记】OI 2020-2021(在更)

    [CSP-S2020初赛] [CSP-S2020] [NOIp 2020] [NOI冬令营 2021] [省选 2021] [NOI 2021]

  9. 【搜索】单词接龙 luogu-1019

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙" ...

  10. 【洛谷1434 [SHOI2002]滑雪】记忆化搜索

    AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...