题目大意:

给一棵树,每次激活或熄灭一个点,每次问这些点都联通起来所需的最小总边权

分析:

若根据dfs序给所有点排序,为$v1,v2,v3....vk$,那么答案就是$(dis(v1,v2)+dis(v2,v3)+...+dis(vk-1,vk)+dis(vk,v1))/2$

只需要动态的维护这个序列,每次拿出前后两个点后用lca修改答案即可

这道题主要是想学习一下set在这方面的使用

毕竟现在开O2的题比比皆是,要是能少写个平衡树岂不美哉(我也不会写233

我们就默认使用的是c++11的标准吧


如何为set重载运算符

首先你要有一个结构体,并在里面重载一个bool类型的()函数,先这样(这里以将数字按d数组的大小排序为例):

struct cmp{bool operator () (const int &a,const int &b){return d[a]<d[b];}};

接下来这样声明set:

set<int,cmp>S;

如何查找一个元素的前驱后继等

我们这里声明迭代器时使用c++11特有的auto用法,看起来方便不少(set<int>::iterator)

这里以查找x的前驱后继为例(循环式的,即若x为最后一个数,后继就是第一个数,反过来同理

auto it=S.lower_bound(x),a=it,b=it;
int l=(it==S.begin()?*--S.end():*--a);
int r=(it==--S.end()?*S.begin():*++b);

注意这里end()函数返回的是个超尾,所以要--

这里我们看到迭代器的移动用加减即可,取值时用*即可

插入删除

insert和erase,千万别记错了

S.insert(x);
S.erase(x);


接下来放上这道题的代码

 1 #include<bits/stdc++.h>
 2 #define N 100005
 3 #define ll long long
 4 using namespace std;
 5 int n,q;
 6 int h[N],to[2*N],nxt[2*N],w[2*N],etop;
 7 void add(int a,int b,int c){to[++etop]=b,nxt[etop]=h[a],w[etop]=c,h[a]=etop;}
 8 int fa[N][20],d[N],tot,dep[N];
 9 ll len[N][20];
10 void dfs(int u){
11     d[u]=++tot;
12     for(int i=1;i<=17;i++){
13         fa[u][i]=fa[fa[u][i-1]][i-1];
14         len[u][i]=len[u][i-1]+len[fa[u][i-1]][i-1];
15         if(fa[u][i]==0)break;
16     }
17     for(int k=h[u],v=to[k];k;k=nxt[k],v=to[k])
18     if(v!=fa[u][0]){
19         fa[v][0]=u;len[v][0]=w[k];
20         dep[v]=dep[u]+1;
21         dfs(v);
22     }
23 }
24 ll LCA(int x,int y){
25     ll ans=0;
26     if(dep[x]<dep[y])swap(x,y);
27     for(int i=17;i>=0;i--)
28     if(fa[x][i]&&dep[fa[x][i]]>=dep[y]){
29         ans+=len[x][i];
30         x=fa[x][i];
31     }
32     if(x==y)return ans;
33     for(int i=17;i>=0;i--)
34     if(fa[x][i]!=fa[y][i]){
35         ans+=len[x][i];
36         ans+=len[y][i];
37         x=fa[x][i];
38         y=fa[y][i];
39     }
40     ans+=len[x][0];
41     ans+=len[y][0];
42     return ans;
43 }
44 struct cmp{bool operator () (const int &a,const int &b){return d[a]<d[b];}};
45 set<int,cmp>S;
46 ll ans;
47 void ins(int x){
48     S.insert(x);
49     auto it=S.lower_bound(x),a=it,b=it;
50     int l=(it==S.begin()?*--S.end():*--a);
51     int r=(it==--S.end()?*S.begin():*++b);
52     ans-=LCA(l,r);
53     ans+=LCA(l,x);
54     ans+=LCA(x,r);
55 }
56 void del(int x){
57     auto it=S.lower_bound(x),a=it,b=it;
58     int l=(it==S.begin()?*--S.end():*--a);
59     int r=(it==--S.end()?*S.begin():*++b);
60     ans+=LCA(l,r);
61     ans-=LCA(l,x);
62     ans-=LCA(x,r);
63     S.erase(x);
64 }
65 char o[2];
66 int main(){
67     scanf("%d",&n);
68     for(int i=1,a,b,c;i<n;i++){
69         scanf("%d%d%d",&a,&b,&c);
70         add(a,b,c),add(b,a,c);
71     }
72     dfs(1);
73     scanf("%d",&q);
74     while(q--){
75         scanf("%s",o);
76         if(o[0]=='?')cout<<ans/2<<endl;
77         else{
78             int x;scanf("%d",&x);
79             if(o[0]=='+')ins(x);
80             else del(x);
81         }
82     }
83     return 0;
84 }

View Code


2019.6.18 update

今天在写一个扫描线题时使用上面的方法重置set的比较符出现了问题,使用lower_bound会在大数据下WA掉,但upper_bound则没问题

如果使用常规的重载运算符的话则两种方式都没问题……(蒙圈ing

这里给个当时的两种比较函数吧

这是出了问题的:

struct cmp{bool operator () (const hu &A,const hu &B){double as=A.y+sqrt(A.r*A.r-(A.x-X)*(A.x-X))*(1.0*A.u);double bs=B.y+sqrt(B.r*B.r-(B.x-X)*(B.x-X))*(1.0*B.u);if(as+eps>bs&&bs+eps>as)return A.u<B.u;else return as<bs;}
};

这个是改成重载运算符的:

bool operator < (const hu &A,const hu &B){double as=A.y+sqrt(A.r*A.r-(A.x-X)*(A.x-X))*(1.0*A.u);double bs=B.y+sqrt(B.r*B.r-(B.x-X)*(B.x-X))*(1.0*B.u);if(as+eps>bs&&bs+eps>as)return A.u<B.u;else return as<bs;
}

如果哪位大神路过希望能指点一下555(;´д`)ゞ

还有NOI没有C++11

所以跟我一起拼一遍

iterator

再来3遍

iterator

iterator

iterator

ojbk!

转载于:https://www.cnblogs.com/2017SSY/p/10948482.html

CF176E Archaeology(set用法提示)相关推荐

  1. 光学字符识别 Tesseract-OCR 的下载、安装和基本用法

    OCR:即Optical Character Recognition,光学字符识别,是指检查纸或者图片上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程: T ...

  2. 4.19、Bootstrap V4自学之路-----内容---提示冒泡

    为什么80%的码农都做不了架构师?>>>    我一直没有调试出来,包裹引入tether.min.js仍然无法出发效果. mark着,回头再看.先熟悉文档. 概述 在使用提示冒泡插件 ...

  3. Bootstrap 提示工具(Tooltip)弹出框

    第一步: 加载3个框架 <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js">< ...

  4. 英语中what的用法

    阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量.文章设置为仅粉丝可见,是因为写博客确实花了不少精力.希望互相进步谢谢!! 码字不易,谢谢点赞!!! 码字不易,谢谢点 ...

  5. interrupt用法C语言,interrupt

    知识点:<interrupt> 收集:茹盒呜 编辑:康乃馨姐姐 本知识点包括:1.1.disturb,interrupt,disrupt的区别 2.单片机中断:interrupt 0 us ...

  6. Excel2019条件语句及嵌套条件语句的用法

    [版权申明] 非商业目的注明出处可自由转载,转载请注明出处 博文地址:https://blog.csdn.net/cdpxc/article/details/109773350 出自:cdpxc(CS ...

  7. perf+火焰图 = 性能分析利器

    perf 1. perf安装 sudo apt install linux-tools-common 检查是否安装好 perf 如果出现 You may need to install the fol ...

  8. meetup_如何使用标准库和Node.js构建Meetup Slack机器人

    meetup by Janeth Ledezma 简妮丝·莱德兹玛(Janeth Ledezma) 如何使用标准库和Node.js构建Meetup Slack机器人 (How to build a M ...

  9. Linux期末复习题库(4)

    [试题分类]: 1.下列哪种说法是错误的( ) . A.操作系统可用于控制和管理计算机系统资源 B.操作系统可用于对各类任务进行调度 C.操作系统可用于完成源代码编译 D.操作系统应为用户提供便捷的操 ...

最新文章

  1. 12W人编程能力暴增!网友:服气!选择比天赋更重要!
  2. 开发语音录入_语言翻译小程序app开发 解决了人们的语言障碍问题
  3. 更易于使用的Retrofit(不用写注解)
  4. vue-typescript
  5. ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)
  6. layui入门基础:资源汇总
  7. 隹悦服务器批量控制软件
  8. Oracle数据库性能问题分析的一种常规思路
  9. 18kw丹佛斯变频器常见故障_变频器常见故障——输出不平衡、过载、开关电源损坏...
  10. 《绝地求生》外挂源代码被公布,或迎神仙大战时代?
  11. 同样是机器学习算法工程师,你的面试为什么过不了?
  12. matlab离散点包络,求大神指点绘制空间内散点图的包络面,,,散点程序如下
  13. word中的方括号怎么删_word中怎么快速删除所有的括号及内容
  14. 程序员的那些事儿 -- 高级程序员买衣服
  15. 如何快速掌握技术和知识点
  16. VirtualBox安装黑群晖并建立smb共享目录的方法
  17. CC00042.kafka——|Hadoopkafka.V27|——|kafka.v27|主题管理.v02|
  18. 第五人格调香师技能可以用几次?
  19. 磁场强度和磁感应强度区别
  20. 企业级360°全方位用户画像:标签系统[四]

热门文章

  1. linux应用程序之----文件操作
  2. ubuntu上使用sqlite3
  3. 2019年最新银行存款利息,有的银行最高给到5.45%
  4. Yammer从Scala转向Java
  5. “像你一样”与海容天天:OPEN国际行为艺术展十周年
  6. 台湾印象之四:风流人物
  7. sql 以a开头的所有记录_SQL开发与数据库管理笔记
  8. 虚拟局域网软件开源_ZeroTier虚拟局域网免费远程桌面体验--替代TeamViewer
  9. python 主要内容,介绍一些有关python的重要内容
  10. matlab计算联合熵,如何用matlab软件计算一幅图像信息的熵以及两幅图像间的联合熵?...