博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF1109F Sasha and Algorithm of Silence's Sounds
阅读量:7048 次
发布时间:2019-06-28

本文共 4298 字,大约阅读时间需要 14 分钟。

 

考虑树的性质:n个点,n-1条边,连通图

前两个用老套路,考虑枚举右端点,线段树维护左端点情况

n不同,但是,一个图是树,那么必然n-(n-1)=1,如果最小值就是1,那么是可以维护的。

所以如果保证这些左端点到r的点构成n-1条边的连通图,就可以直接求答案了。

但是并不一定只有n-1条边,有n-1条边也可能不连通

考虑不一定有n-1条边,和有n-1条边但是不连通的条件是:有环!

只有[l,r]没有环,才可能之后会构成一个树

并且我们可以发现,[l,r]有环,那么l'<=l,r'>=r的[l',r']都一定有环

所以可以尺取法!

枚举R的同时,L卡住左边界,使得[L,R]没有环。LCT维护一下

只有左端点位于[L,R]才可能是树,且点数-边数最小值是1

维护最小值和最小值出现次数即可。

#include
#define reg register int#define il inline#define fi first#define se second#define mk(a,b) make_pair(a,b)#define numb (ch^'0')#define pb push_back#define solid const auto &#define enter cout<
using namespace std;typedef long long ll;template
il void rd(T &x){ char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}template
il void output(T x){
if(x/10)output(x/10);putchar(x%10+'0');}template
il void ot(T x){
if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}template
il void prt(T a[],int st,int nd){ for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}namespace Modulo{const int mod=998244353;int ad(int x,int y){ return (x+y)>=mod?x+y-mod:x+y;}void inc(int &x,int y){x=ad(x,y);}int mul(int x,int y){ return (ll)x*y%mod;}void inc2(int &x,int y){x=mul(x,y);}int qm(int x,int y=mod-2){ int ret=1;while(y){ if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}}//using namespace Modulo;namespace Miracle{const int N=2e5+5;const int inf=0x3f3f3f3f;const int mv[4][2]={ {+1,0},{-1,0},{ 0,-1},{ 0,+1}};int a[2002][2002];int n;int ha,li;pair
pos[N];struct node{ int ch[2]; int fa; int rev;}t[N];int L,R;bool nrt(int x){ return (t[t[x].fa].ch[0]==x||t[t[x].fa].ch[1]==x);}void rotate(int x){ int y=t[x].fa,d=t[y].ch[1]==x; t[t[y].ch[d]=t[x].ch[!d]].fa=y; if(nrt(y)) t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x; else t[x].fa=t[y].fa; t[t[x].ch[!d]=y].fa=x;}int sta[N];#define ls t[x].ch[0]#define rs t[x].ch[1]void rev(int x){ t[x].rev^=1; swap(t[x].ch[0],t[x].ch[1]);}void pd(int x){ if(t[x].rev){ rev(ls);rev(rs); t[x].rev=0; }}void splay(int x){ int y=x,z=0; sta[++z]=y; while(nrt(y)) y=t[y].fa,sta[++z]=y; while(z) pd(sta[z--]); while(nrt(x)){ y=t[x].fa,z=t[y].fa; if(nrt(y)){ rotate((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x); } rotate(x); }}void access(int x){ for(reg y=0;x;y=x,x=t[x].fa){ splay(x);t[x].ch[1]=y; }}void makert(int x){ access(x);splay(x);rev(x);}int findrt(int x){ access(x);splay(x); while(t[x].ch[0]) x=t[x].ch[0]; splay(x); return x;}bool link(int x,int y){ makert(x); if(findrt(y)!=x){ t[x].fa=y; return true; }else return false;}void cut(int x,int y){ makert(x);access(y);splay(y); if(t[y].ch[0]==x&&!t[x].ch[0]&&!t[x].ch[1]){ t[x].fa=0;t[y].ch[0]=0; }}void dele(int x){ int nx=pos[x].fi,ny=pos[x].se; for(reg i=0;i<4;++i){ int tx=nx+mv[i][0],ty=ny+mv[i][1]; if(a[tx][ty]){ int p=a[tx][ty]; if(p>=L&&p<=R){ cut(x,p); } } }}int got[10];bool che(int x){ bool fl=true; int nx=pos[x].fi,ny=pos[x].se; int ct=0; for(reg i=0;i<4;++i){ int tx=nx+mv[i][0],ty=ny+mv[i][1]; if(a[tx][ty]){ int p=a[tx][ty]; if(p>=L&&p<=R){ bool lp=link(x,p); if(lp==false) { fl=false;break; } got[++ct]=p; } } } if(!fl){ for(reg i=1;i<=ct;++i) cut(x,got[i]); } return fl;}#undef ls#undef rsstruct po{ int mi,cnt; po(){mi=inf,cnt=1;} po friend operator +(po a,po b){ po c;c.mi=min(a.mi,b.mi);c.cnt=0; if(a.mi==c.mi) c.cnt+=a.cnt; if(b.mi==c.mi) c.cnt+=b.cnt; return c; }};namespace seg{struct tr{ po v; int add;}t[4*N];#define ls (x<<1)#define rs (x<<1|1)#define mid ((l+r)>>1)void pushup(int x){ t[x].v=t[ls].v+t[rs].v;}void tag(int x,int c){ t[x].add+=c; t[x].v.mi+=c;}void pushdown(int x){ if(t[x].add){ tag(ls,t[x].add);tag(rs,t[x].add); t[x].add=0; }}void build(int x,int l,int r){ if(l==r){ t[x].add=0;t[x].v.mi=0;t[x].v.cnt=1;return; } build(ls,l,mid); build(rs,mid+1,r); pushup(x);}void upda(int x,int l,int r,int L,int R,int c){ if(L<=l&&r<=R){ tag(x,c);return; } pushdown(x); if(L<=mid) upda(ls,l,mid,L,R,c); if(mid
=L&&p<=R){ seg::upda(1,1,n,L,p,-1); } } } po now=seg::query(1,1,n,L,R); if(now.mi==1){ ans+=now.cnt; } } ot(ans); return 0;}}signed main(){ Miracle::main(); return 0;}/* Author: *Miracle**/

本题处理树的连通性还是不错的思路:变成处理有没有环

环可以尺取法处理,使得边数<=n-1,然后点数-边数最小是1,就保证了是一棵树。

转载于:https://www.cnblogs.com/Miracevin/p/10988197.html

你可能感兴趣的文章
数据结构-串
查看>>
Java数据类型转换浅析
查看>>
在 vs2017 中使用 C# 7 新特性。
查看>>
Oracle 数据集操作符浅析(Union;Union All,Minus,Intersect)
查看>>
头条前端笔试最后一道题
查看>>
windows 2003 IIS 设置 FTP被动模式
查看>>
网络编程-线程,守护线程,线程互斥锁-26
查看>>
监听INPUT值的即时变化
查看>>
Comparator比较器对ArrayList排序
查看>>
结对-结对编程项目作业名称-结对项目总结
查看>>
团队-象棋游戏-模块测试过程
查看>>
[LeetCode]Self Crossing
查看>>
Linq学习总结2--Linq to XML
查看>>
BZOJ 2839 集合计数
查看>>
Luogu P4450 双亲数
查看>>
JavaBean与Map的相互转换
查看>>
CRM系统模型
查看>>
Cocos Lua的Touch 点击事件添加
查看>>
zabbix实现mysql数据库的监控(二)
查看>>
Select2 多层次赋值时异步赋值的问题
查看>>