这道题一看就是可持久化并查集 然后我就愉快的yy了一波 还是错掉了qwqwqwqwq

方法是对的 就是我每次在树上查询$fa$的时候我还压缩了路径 导致这玩意空间炸掉了

所以要保证时间复杂度 就启发式合并 也就是$size$小的往$size$大的搞

这样子就保证每次合并的时候连通块元素个数每次至少乘以$2$ 也就是保证了层数是$log$级的

代码

#include <bits/stdc++.h>
using namespace std;const int N = 1e5 + 5;
int n,f[90 * N],ls[90 * N],rs[90 * N],size[90 * N],root[N];
int cnt,m,fa[N];int build(int o, int l ,int r) {int nd = ++ cnt;if(l == r) {f[nd] = l; size[nd] = 1;return nd;}int mid = (l + r) >> 1;ls[nd] = build(2 * o, l, mid);rs[nd] = build(2 * o + 1, mid + 1, r);return nd;
}void Init( ) {scanf("%d%d",& n,& m);root[0] = build(1, 1, n);
}int modify_fa(int pre, int o, int l, int r, int pos, int del) {int nd = ++ cnt;f[nd] = f[pre],ls[nd] = ls[pre],rs[nd] = rs[pre],size[nd] = size[pre];if(l == r) {f[nd] = del; return nd;}int mid = (l + r) >> 1;if(pos <= mid) {ls[nd] = modify_fa(ls[pre], 2 * o, l, mid, pos, del);}else rs[nd] = modify_fa(rs[pre], 2 * o + 1, mid + 1, r, pos, del);return nd;
}int modify_size(int pre, int o, int l, int r, int pos, int del) {int nd = ++ cnt;f[nd] = f[pre],ls[nd] = ls[pre],rs[nd] = rs[pre],size[nd] = size[pre] + del;if(l == r) {return nd;}int mid = (l + r) >> 1;if(pos <= mid) {ls[nd] = modify_size(ls[pre], 2 * o, l, mid, pos, del);}else rs[nd] = modify_size(rs[pre], 2 * o + 1, mid + 1, r, pos, del);return nd;
}int query_fa(int nd, int o, int l, int r, int pos) {if(l == r) {return f[nd];}int mid = (l + r) >> 1;if(pos <= mid) return query_fa(ls[nd], 2 * o, l, mid, pos);else return query_fa(rs[nd], 2 * o + 1, mid + 1, r, pos);
}int query_size(int nd, int o, int l, int r, int pos) {if(l == r) {return size[nd];}int mid = (l + r) >> 1;if(pos <= mid) return query_size(ls[nd], 2 * o, l, mid, pos);else return query_size(rs[nd], 2 * o + 1, mid + 1, r, pos);
}int Find_fa(int x, int M) {int ff = query_fa(root[x], 1, 1, n, M);if(ff == M) return ff;int F = Find_fa(x, ff);return F;
}void Solve( ) {int las = 0;for(int i = 1;i <= m;i ++){int opt,x,y;scanf("%d",& opt);if(opt == 1) {scanf("%d%d",& x,& y); x = x + las, y = y + las;int fa1 = Find_fa(i - 1, x), fa2 = Find_fa(i - 1, y);if(fa1 == fa2) {root[i] = root[i - 1]; continue;}int s1 = query_size(root[i - 1], 1, 1, n, fa1);int s2 = query_size(root[i - 1], 1, 1, n, fa2);if(s1 < s2) { swap(s1,s2); swap(fa1, fa2); }root[i] = modify_fa(root[i - 1], 1, 1, n, fa2, fa1);root[i] = modify_size(root[i], 1, 1, n, fa1, s2);}else {scanf("%d%d",& x,& y); x = x + las, y = y + las;root[i] = root[i - 1]; int fat = Find_fa(x, y);int s = query_size(root[x], 1, 1, n, fat);printf("%d\n",s); las = s;}  }
}int main( ) {freopen("build.in","r",stdin);freopen("build.out","w",stdout);Init( );Solve( );
}

这道题班上有人用贪心A掉了

而蒟蒻我只会垃圾dp  qwqwq 首先我们可以发现这个玩意正着来搞是不行的

因为每个人一旦选择这座城市自己要 那么他的下一个人的选择是确定的

并且后面的选择跟前面的毫无联系 就无法体现最优选择的思想 所以我们考虑倒着搞 维护一个$sum$前缀和

$dp[i][0/1][0/1]$表示到了第$i$个城市 当前是谁的回合 这个人选不选择这个城市 这个人获得的最大收益

$dp[i][now][1] = sum[n] - sum[i] + a[i] - max(dp[i +1][now xor 1][0],dp[i + 1][now xor 1][1])$

表示如果我选择这座城市 相当于把主动权给别人 那么下个人一定会选择它的最优方案 总的收益是一定的 所以就用总收益减去别人的收益就可以了

$dp[i][now][0] = max(dp[i + 1][now][1],dp[i + 1][now][0])$

表示如果我这个位置不选 我的最大收益就是后面的选择所带来的最大收益

代码

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
const int N = 1e5 + 5;
int n;
ll dp[N][2][2],sum[N],a[N];void Init( ) {scanf("%d",& n);for(int i = 1;i <= n;i ++) {scanf("%lld",& a[i]);sum[i] = sum[i - 1] + a[i];}
}void Solve( ) {dp[n][1][1] = a[n], dp[n][0][1] = a[n];for(int i = n - 1;i >= 1;i --) {for(int now = 0;now <= 1;now ++) {dp[i][now][1] = a[i] + sum[n] - sum[i] - max(dp[i + 1][now ^ 1][0], dp[i + 1][now ^ 1][1]);dp[i][now][0] = max(dp[i + 1][now][1], dp[i + 1][now][0]);}}printf("%lld\n",max(dp[1][1][1], dp[1][1][0]));
}int main( ) {freopen("distribute.in","r",stdin);freopen("distribute.out","w",stdout);Init( );Solve( );
}

然后我考试的时候做不来这道题

emmmmmm考虑要存在合法的圆边那么他肯定存在于一个环里面 在无向图里面 他肯定是一个点双连通分量

所以把每个点双处理出来 如果边数等于点数 他就是一个合法简单环 否则会有不止一个环 就不合法

考虑为什么是点双连通 不是边双呢 因为只有点双才是多个简单环叠加

左边这个虽然是边双 但是他是合法的 若是按照之前的方法 他会被判断成不合法 因为他不是简单环的叠加 而点双就一定是叠加 判断就一定合法

代码

#include <bits/stdc++.h>
using namespace std;const int N = 1e5 + 5;
int n,head[N],nex[2 * N],tov[2 * N],id[2 * N],c[N];
int dfn[N],low[N],idc,tot = 1,m,stk[2 * N],top,col,que[2 * N];
bool vis[2 * N],isans[2 * N];void add(int u, int v, int ID) {tot ++;nex[tot] = head[u];tov[tot] = v; id[tot] = ID;head[u] = tot;
}void Init( ) {scanf("%d%d",& n,& m);for(int i = 1;i <= m;i ++) {int u,v;scanf("%d%d",& u,& v);add(u, v, i); add(v, u, i);}
}void tarjan(int u,int from) {low[u] = dfn[u] = ++idc;for(int i = head[u];i;i = nex[i]) {int v = tov[i];if((i ^ 1) == from) continue;if(! vis[i]) vis[i] = vis[i ^ 1] = true, stk[++ top] = i;if(! dfn[v]) {tarjan(v, i);low[u] = min(low[u], low[v]);if(low[v] >= dfn[u]) {col ++; int cntn = 0,cnte = 0;while(1) {int e = stk[top --];if(c[tov[e]] != col) c[tov[e]] = col,cntn ++;if(c[tov[e ^ 1]] != col) c[tov[e ^ 1]] = col, cntn ++;que[++ cnte] = e;if(e == i) break;}if(cnte == cntn) {for(int i = 1;i <= cnte;i ++) isans[que[i]] = isans[que[i] ^ 1] = true;}}}else if(low[u] > dfn[v]) low[u] = min(low[u], dfn[v]);}
}void Solve( ) {for(int i = 1;i <= n;i ++) {if(! dfn[i]) tarjan(i, 0);}int ans = 0;for(int i = 2;i <= tot;i += 2) if(isans[i]) ans ++;printf("%d\n",ans);for(int i = 2;i <= tot;i += 2) if(isans[i]) printf("%d ",i / 2);
}int main( ) {freopen("find.in","r",stdin);freopen("find.out","w",stdout);Init( );Solve( );
}

转载于:https://www.cnblogs.com/Rubenisveryhandsome/p/9690596.html

18.9.22 考试总结相关推荐

  1. [18/11/22] 将点分十进制的IP地址化成二进制输出

    1 #include <stdio.h> 2 void binary(int d){ 3 int i=0,j,n,b[8]={0}; 4 while(d>0){ 5 n=d%2; 6 ...

  2. 解决Ubuntu 18.04-Ubuntu 22.04中文输入法安装依赖的问题,成功安装搜狗拼音

    首先安装fcitx 一.检测是否安装fcitx 首先检测是否有fcitx,因为搜狗拼音依赖fcitx > fcitx 提示: 程序"fcitx"尚未安装. 您可以使用以下命令 ...

  3. MySQL查年龄18到22的信息_MySQL之单表查询

    1.查询所有老师的信息 select*fromteacher; 2.在没有表被引用的情况下,允许使用dual作为一个假的表名 selectnow()fromdual;select1+1fromdual ...

  4. 日报 18/07/22 您的设计模式!终于有时间开写~ ~

    1/24: 策略模式 strategypattern 先给大家将一种本人自认为简单的设计模式~ 刘备要到江东娶老婆了,走之前诸葛亮给赵云(伴郎)三个锦囊妙计,说是按天机拆开解决棘手问题, 嘿,还别说, ...

  5. 18.8.20 考试总结

    铁塔 (tower.pas/c/cpp) 题目描述 Rainbow 和Freda 要在Poetic Island 市的一座山脚下盖房子定居了--盖房子需要钢材 ,幸运的是,这里有排成一行的n 座废弃的 ...

  6. 山科大 6-1 sdust-Java-可实现多种排序的Book类 (20 分)(18 软件 期中考试函数1)

    设计Book类,要求:1)Book类的成员属性包括:书名name(String类型).出版日期publishDate(Date类型).定价price(double型):2)为Book对象提供按出版日期 ...

  7. 思维导图 基础篇(18)TBLI 考试内容 评分标准

    1 TBLI的考试内容主要分为3个部分 思维导图 艺术创作:这里会给出一个主题,比如思维大图在生活中的应用.思维导图的意义...等.之后根据主题 会指出一副标准的思维导图.时长共2小时. 思维导图 高 ...

  8. 18.10.24 考试总结

    我永远讨厌blutrex的题目靴靴 这道题就是一道裸裸欧拉回路 但是由于我之前并没有写过.... 真的难受QAQ 这道题首先想到建图是对于每一个简单词看作图上的边 某单词$ab$就建边$a -> ...

  9. 18.4.1 考试解题报告 P71

    题目:https://files.cnblogs.com/files/lovewhy/problem.pdf 偷偷摘来dalao题面. P71 竞赛时间:???? 年?? 月?? 日??:??-??: ...

最新文章

  1. 平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。
  2. Linux Redis自动化挖矿感染蠕虫分析及安全建议
  3. c语言怎么在编码时改变颜色,怎么给贪吃蛇换一个颜色 怎么改 代码如下
  4. Web 前端框架分类解读
  5. PyTorch框架学习十四——学习率调整策略
  6. 信息学奥赛一本通 2048:【例5.18】串排序
  7. Kafka—配置SASL/PLAIN认证客户端及常用操作命令
  8. wamp配置中的大小写
  9. 5.2自动扫描及装配数据
  10. gimp中文版教程_Gimp中文经典入门实用教程.pdf
  11. JAVA JDK 官网安装包启动后没反应
  12. Python 各种画图
  13. 物业服务的品质、成本与四保一服的数字化方法
  14. 【矩阵论】广义特征值问题
  15. sql数据库读取oracle数据库,SQL Server 数据导入Oracle数据库(脚本实现)
  16. android温湿度传感节点指令源代码,Arduino+DHT11+OLED显示温湿度信息(附详细文档+源码)...
  17. vscode和IDEA分别如何克隆git上的项目
  18. C语言基础-函数的概念
  19. 163邮箱接口post登录战网(一)
  20. win10如何手动强制关联默认文件打开方式应用

热门文章

  1. cpu 被挂起和阻塞_同步异步阻塞非阻塞并发并行讲解
  2. 住170平以上的大平层大户型什么感觉?
  3. 事业编和公务员哪个好?
  4. 清晨一杯水,到底怎么喝才算健康?
  5. 和媳妇加一起月薪三万五想换车了不知道x5养的起吗?
  6. 现在市面上卖的贵州茅台镇原浆酒20元一瓶是什么酒?
  7. 能搞垮你的不止是同行
  8. 做企业:要么靠规模,要么靠利润
  9. 我哥以前是做小本生意的,一年花销除外能存个十二万的样子
  10. This time, ZTE has released the world‘s first