传送门


构成一棵树可以分成两个限制:图不成环、图的点数-边数=1。

我们考虑枚举右端点\(r\)计算所有可能的左端点\(l\)的答案。我们先考虑第一个限制:图不成环。注意到当\(r\)确定的时候,满足这个条件的\(l\)一定是一段后缀。设\(p_r\)表示满足图不成环时最小的\(l\),还可以发现\(p_r\)是单调不降的。那么我们可以使用双指针维护,在\(r\)增加\(1\)的时候使用LCT维护\(p_r\)的值。

接下来在每一个\(p_r\)求完之后,考虑图的点数-边数=1的限制。每一次\(r\)增加\(1\)的时候,都会增加一些新的可能的边。找到在矩阵上与\(r\)相邻且值在\([l,r]\)内的元素,设其中某一个的元素值为\(x\),那么在\(l \leq x\)的时候边\((x,r)\)就会出现。我们可以使用线段树维护每一个左端点的点数-边数,每一次增加一些新点和新边就是前缀加减的过程。

最后我们需要查询线段树中值为\(1\)的数的个数。这在区间加法下似乎不太可做,但是注意到如果将不合法位置的值设为INF,那么线段树中\(1\)一定是最小值。所以就相当于是一个求区间最小值数量的问题,就可以使用线段树去做了。

#include<bits/stdc++.h>
using namespace std;int read(){int a = 0; char c = getchar(); bool f = 0;while(!isdigit(c)){f = c == '-'; c = getchar();}while(isdigit(c)){a = a * 10 + c - 48; c = getchar();}return f ? -a : a;
}#define id(i , j) ((i - 1) * M + j)
#define PII pair < int , int >
const int _ = 2e5 + 3 , dir[4][2] = {0,1,0,-1,1,0,-1,0};
int N , M , L = 1 , R , arr[_]; long long cnt; PII to[_];namespace segt{int mn[_ << 2] , cnt[_ << 2] , mrk[_ << 2];#define mid ((l + r) >> 1)
#define lch (x << 1)
#define rch (x << 1 | 1)void init(int x , int l , int r){mn[x] = 1e9; cnt[x] = r - l + 1; if(l != r){init(lch , l , mid); init(rch , mid + 1 , r);}}void mark(int x , int val){mrk[x] += val; mn[x] += val;}void down(int x){mark(lch , mrk[x]); mark(rch , mrk[x]); mrk[x] = 0;}void up(int x){mn[x] = min(mn[lch] , mn[rch]); cnt[x] = (mn[x] == mn[lch]) * cnt[lch] + (mn[x] == mn[rch]) * cnt[rch];}void modify(int x , int l , int r , int L , int R , int val){if(l >= L && r <= R) return mark(x , val);down(x);if(mid >= L) modify(lch , l , mid , L , R , val);if(mid < R) modify(rch , mid + 1 , r , L , R , val);up(x);}
}namespace LCT{int fa[_] , ch[_][2]; bool rmrk[_];bool nroot(int x){return ch[fa[x]][0] == x || ch[fa[x]][1] == x;}bool son(int x){return ch[fa[x]][1] == x;}void mark(int x){rmrk[x] ^= 1; swap(ch[x][0] , ch[x][1]);}void down(int x){if(rmrk[x]){mark(ch[x][0]); mark(ch[x][1]); rmrk[x] = 0;}}void dall(int x){if(nroot(x)) dall(fa[x]); down(x);}void rot(int x){bool f = son(x); int y = fa[x] , z = fa[y] , w = ch[x][f ^ 1];fa[x] = z; if(nroot(y)) ch[z][son(y)] = x;fa[y] = x; ch[x][f ^ 1] = y;ch[y][f] = w; if(w) fa[w] = y;}void splay(int x){dall(x); while(nroot(x)){if(nroot(fa[x])) rot(son(fa[x]) == son(x) ? fa[x] : x); rot(x);}}void access(int x){for(int y = 0 ; x ; y = x , x = fa[x]){splay(x); ch[x][1] = y;}}int fdrt(int x){access(x); splay(x); while(ch[x][0]) down(x = ch[x][0]); splay(x); return x;}void mkrt(int x){access(x); splay(x); mark(x);}void split(int x , int y){mkrt(x); access(y); splay(y);}void link(int x , int y){mkrt(x); fa[x] = y;}void cut(int x , int y){split(x , y); ch[y][0] = fa[x] = 0;}
}void cut(){PII pos = to[L]; segt::modify(1 , 1 , N * M , L , L , 1e9);for(int i = 0 ; i < 4 ; ++i){int x = pos.first + dir[i][0] , y = pos.second + dir[i][1];if(x > 0 && x <= N && y > 0 && y <= M && LCT::fdrt(arr[id(x , y)]) == LCT::fdrt(L))LCT::cut(arr[id(x , y)] , L);}++L;
}void link(){PII pos = to[R];for(int i = 0 ; i < 4 ; ++i){int x = pos.first + dir[i][0] , y = pos.second + dir[i][1];if(x > 0 && x <= N && y > 0 && y <= M){int t = arr[id(x , y)];while(t >= L && LCT::fdrt(t) == LCT::fdrt(R)) cut();if(t >= L && t <= R) LCT::link(t , R);}}for(int i = 0 ; i < 4 ; ++i){int x = pos.first + dir[i][0] , y = pos.second + dir[i][1];if(x > 0 && x <= N && y > 0 && y <= M && arr[id(x , y)] >= L && arr[id(x , y)] <= R)segt::modify(1 , 1 , N * M , 1 , arr[id(x , y)] , -1);}
}int main(){N = read(); M = read(); segt::init(1 , 1 , N * M);for(int i = 1 ; i <= N ; ++i) for(int j = 1 ; j <= M ; ++j) to[arr[id(i , j)] = read()] = PII(i , j);while(++R <= N * M){segt::modify(1 , 1 , N * M , R , R , -1e9);segt::modify(1 , 1 , N * M , 1 , R , 1); link();cnt += (segt::mn[1] == 1) * segt::cnt[1];}cout << cnt; return 0;
}

转载于:https://www.cnblogs.com/Itst/p/11514740.html

CF1109F Sasha and Algorithm of Silence's Sounds LCT、线段树相关推荐

  1. Codeforces 1109F. Sasha and Algorithm of Silence's Sounds

    Description 给出一个 n∗mn*mn∗m 的网格图,保证所有位置上的数形成一个 1−n∗m1 -n*m1−n∗m 的排列. 问有多少个值域区间 [l,r][l,r][l,r] 满足,在 [ ...

  2. [多校联考-西南大学附中]切面包(线段树/概率与期望)+ Slow Path Finding Algorithm(拓扑排序/DP)+ 分数转化(数论)

    文章目录 T1:分数转换 题目 题解 代码实现 T2:Slow Path Finding Algorithm 题目 题解 代码实现 T3:切面包 题目 题解 代码实现 T1:分数转换 题目 Time ...

  3. CF719E. Sasha and Array [线段树维护矩阵]

    CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...

  4. Sasha and a Very Easy Test CodeForces - 1109E (数学,线段树)

    大意: 给定n元素序列, q个操作: (1)区间乘 (2)单点除(保证整除) (3)区间求和对m取模 要求回答所有操作(3)的结果 主要是除法难办, 假设单点除$x$, $x$中与$m$互素的素因子可 ...

  5. Codeforces Round #539 (Div. 1)

    有史以来打的最烂的一场...B题都WA了两发,D题数树不知道结论不会做,E题没调出来...GG了. 也说明我实力其实还不够吧...再多加练习,我还有机会继续努力. 题目链接 A. Sasha and ...

  6. 各种模板(数据结构图论)

    文章目录 数据结构 LCT 线段树 线段树分治 树状数组 图论 Tarjan 静态仙人掌 最小生成树 最短路-Floyd 最短路-Dijkstra 最短路-Bellman-Ford 最短路-SPFA ...

  7. SDOI2017 Round1解题报告

    虽然考的很差,很不想去再面对这套题,但是只有直面失败才能走向成功.从新审视这套题,才发现自己存在的问题和差距. Day 1 T1 题解 mobius反演... ∏ni=1∏mj=1fi[gcd(i,j ...

  8. 【codeforces 718 CD】C. Sasha and ArrayD. Andrew and Chemistry

    C. Sasha and Array 题目大意&题目链接: http://codeforces.com/problemset/problem/718/C 长度为n的正整数数列,有m次操作,$o ...

  9. `Supimo` `Algorithm` 算法代码模板CodeTemplate

    catalog 基础模板 源代码 LeetCode源代码 宏定义 常量 浮点数工具Double-Tools 字符串工具String-Tools 十进制整数工具Integer-Tools 二进制数函数 ...

  10. Contest2071 - 湖南多校对抗赛(2015.03.28)

    Contest2071 - 湖南多校对抗赛(2015.03.28) 本次比赛试题由湖南大学ACM校队原创 http://acm.csu.edu.cn/OnlineJudge/contest.php?c ...

最新文章

  1. 阿里CEO张勇放话,90%产品岗将由技术产生,不懂技术的产品人被out了吗?
  2. elasticsearch ——id字段说明,内部是_uid
  3. 关于眼界、眼光、眼前的哪些....
  4. kafka删除主题数据和删除主题
  5. 第一章数据库系统基础
  6. JAVA程序员面试必知32个知识点
  7. Oracle 中调用外部C动态库函数
  8. 韩国小哥哥用Pytorch实现谷歌最强NLP预训练模型BERT | 代码
  9. 关于Websockets问题:
  10. 苹果手用计算机解锁手机密码,苹果手机怎么强制解锁 iPhone强制解锁密码教程...
  11. tkinter GUI 客户端页面编程 登录注册案例开发
  12. Premiere CS4无法导出视频
  13. nginxconsul
  14. matlab画箱型图均值方差,Matlab 绘制箱线图
  15. Oracle性能调优之/*+parallel(t,8)*/
  16. 2019年,SEO关键词KPI考核指标有哪些? 1
  17. 在竞争激烈的情况下,ReentrantLock与CAS的性能比较
  18. 最赚钱的十大增值业务
  19. edge浏览器如何把网页放到桌面_win10系统设置edge浏览器快捷方式放到桌面的操作方法...
  20. 【数据集处理】WiderPerson介绍以及转YOLO格式(图片教程及代码----超详细)

热门文章

  1. python实现随机产生数据矩阵,将txt文件写入Excel中以及转置后写入Excel中
  2. 2021-08-20JSP内置对象及作用域
  3. 2021-08-08 idea 连接Mysql
  4. mysql 触发器 实例_MySQL触发器简单用法示例
  5. classcastexception异常_Java程序员必备:异常的十个关键知识点
  6. FISCO BCOS 微众银行 WeDPR 隐私解决方案 资料汇总
  7. kubectl apply -f weave.yaml之后dns没有启动起来 weave-net CrashLoopBackOff
  8. matlab如何制作莫兰散点图,求大神指点绘制空间内散点图的包络面,,,散点程序如下...
  9. pp什么叫php的事务,ThinkPHP5.0框架事务处理操作简单示例
  10. oracle把一列更新为空,ORA-01439:要更改数据类型,则要修改的列必须为空