2019-XDU-onsite

 ACM  set 󰈭 585字

1427 qko的宝可梦 (已补)

1428 qko的串

1429 qko的进化公式

1430 qko的树

1427 set对有序链的维护

set中每个节点拥有最小攻击力和最大攻击力,保证set中一定满足严格的偏序关系,即保证两个元素之间一定有某元素的最大值全部小于另一个元素的最小值。

初始将1号宝可梦插入到set中,然后遍历2-n宝可梦,通过lower_bound和upper_bound来获得set中“相等“的那些元素。这里的相等意味着不存在严格的偏序关系,那么也就意味着两者互相可以击败,从而这些元素都可以与第i个元素互相可达,应该合并成一个SCC。遍历所有这些相等的元素,将信息进行不断合并,最后将新元素再插入到set中,这样就可以保证set中的严格偏序关系,输出结果时将最后一个元素的个数输出即可。

算法非常精妙,由其是利用set进行合并和查询的操作值得学习!

原来set可以用lower/upper_bound来进行二分,之前我还在苦恼地想怎么才能在set中进行二分,orz

 1const int manx = 1e5 + 10;
 2
 3int a[maxn][15];
 4
 5int n, k;
 6struct NODE{
 7    int m[10], M[10], size;
 8    bool operator < (NODE const &b)const{
 9        for(int i = 0; i < k; i++) if(M[i] > b.m[i]) return 0;
10        return 1;
11    }
12}node[maxn];
13set<NODE> s;
14set<NODE>::iterator p, q, it;
15
16int main(){
17//    Fastin;
18    scanf("%d %d", &n, &k);
19    for(int i = 0; i < n; i++) for(int j = 0; j < k; j++){
20        scanf("%d", node[i].m + j); node[i].size = 1;
21        node[i].M[j] = node[i].m[j];
22    }
23    s.insert(node[0]);
24    for(int i = 1; i < n; i++){
25        NODE temp = node[i];
26        p = s.lower_bound(temp);
27        q = s.upper_bound(temp);
28        it = p;
29        while(it != q){
30            for(int i = 0; i < k; i++){
31                temp.m[i] = min(temp.m[i], it->m[i]);
32                temp.M[i] = max(temp.M[i], it->M[i]);
33            }
34            temp.size += it->size;
35            s.erase(it++);
36        }
37        s.insert(temp);
38        if(i >= 1) printf("%d\n", s.rbegin()->size);
39    }
40    return 0;
41}
嗨! 这里是 rqdmap 的个人博客, 我正关注 GNU/Linux 桌面系统, Linux 内核, 后端开发, Python, Rust 以及一切有趣的计算机技术! 希望我的内容能对你有所帮助~
如果你遇到了任何问题, 包括但不限于: 博客内容说明不清楚或错误; 样式版面混乱等问题, 请通过邮箱 rqdmap@gmail.com 联系我!
修改记录:
  • 2023-09-01 18:14:49单独划分ACM专题; 移动部分博客进入黑洞归档
  • 2023-05-29 23:05:14大幅重构了python脚本的目录结构,实现了若干操作博客内容、sqlite的助手函数;修改原本的文本数 据库(ok)为sqlite数据库,通过嵌入front-matter的page_id将源文件与网页文件相关联
  • 2023-05-08 21:44:36博客架构修改升级
  • 2022-11-16 01:27:34迁移老博客文章内容
2019-XDU-onsite