ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1270H Number of Components

2021-01-24 20:05:26  阅读:133  来源: 互联网

标签:return cur val rs int Number CF1270H Components leqslant


不难发现连通块一定是连续的一段。考虑枚举连通块的右端点 \(p\),要求 \([1,p]\) 和 \([p+1,n]\) 之间没有连边,即 \(\min\limits_{1 \leqslant i \leqslant p} a_i > \max\limits_{p+1 \leqslant i \leqslant n} a_i\)。

设 \(w=\max\limits_{p+1 \leqslant i \leqslant n} a_i\),将 \(>w\) 的位置设为 \(1\),\(\leqslant w\) 的位置设为 \(0\)。合法的 \(w\) 一定会得到一个形如 \(1111100000\) 的 \(01\) 序列,\(1\) 的个数为 \(p\),枚举 \(w\) 就等价于枚举 \(p\)。

设 \(a_0=\infty,a_{n+1}=0\),合法的 \(w\) 对应的 \(01\) 序列中只有一对相邻的 \(1,0\),当 \(w\in\left[ \min\{a_i,a_{i+1}\},\max\{a_i,a_{i+1}\} \right)\) 时会产生一对相邻的 \(1,0\)。

那么在线段树上维护值域,维护区间最小值,当最小值为 \(1\) 时,该区间才能产生贡献。

#include<bits/stdc++.h>
#define maxn 1000010
#define maxm 4000010
#define all 1000001
#define ls (cur<<1)
#define rs (cur<<1|1)
#define mid ((l+r)>>1)
using namespace std;
template<typename T> inline void read(T &x)
{
    x=0;char c=getchar();bool flag=false;
    while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    if(flag)x=-x;
}
int n,q,root=1;
int a[maxn],mn[maxm],val[maxm],tag[maxm];
void pushup(int cur)
{
    if(mn[ls]<mn[rs]) mn[cur]=mn[ls],val[cur]=val[ls];
    else if(mn[ls]>mn[rs]) mn[cur]=mn[rs],val[cur]=val[rs];
    else mn[cur]=mn[ls],val[cur]=val[ls]+val[rs];
}
void pushtag(int cur,int v)
{
    mn[cur]+=v,tag[cur]+=v;
}
void pushdown(int cur)
{
    if(!tag[cur]) return;
    pushtag(ls,tag[cur]),pushtag(rs,tag[cur]),tag[cur]=0;
}
void update(int l,int r,int pos,int v,int cur)
{
    if(l==r)
    {
        val[cur]+=v;
        return;
    }
    pushdown(cur);
    if(pos<=mid) update(l,mid,pos,v,ls);
    else update(mid+1,r,pos,v,rs);
    pushup(cur);
}
void modify(int L,int R,int l,int r,int v,int cur)
{
    if(L>R) return;
    if(L<=l&&R>=r)
    {
        pushtag(cur,v);
        return;
    }
    pushdown(cur);
    if(L<=mid) modify(L,R,l,mid,v,ls);
    if(R>mid) modify(L,R,mid+1,r,v,rs);
    pushup(cur);
}
int query(int L,int R,int l,int r,int cur)
{
    if(L<=l&&R>=r) return mn[cur]==1?val[cur]:0;
    int v=0;
    pushdown(cur);
    if(L<=mid) v+=query(L,R,l,mid,ls);
    if(R>mid) v+=query(L,R,mid+1,r,rs);
    return v;
}
int main()
{
    read(n),read(q),a[0]=all;
    for(int i=1;i<=n;++i) read(a[i]),update(0,all,a[i],1,root);
    for(int i=0;i<=n;++i)
        modify(min(a[i],a[i+1]),max(a[i],a[i+1])-1,0,all,1,root);
    while(q--)
    {
        int x;
        read(x),update(0,all,a[x],-1,root);
        modify(min(a[x],a[x+1]),max(a[x],a[x+1])-1,0,all,-1,root);
        modify(min(a[x-1],a[x]),max(a[x-1],a[x])-1,0,all,-1,root);
        read(a[x]),update(0,all,a[x],1,root);
        modify(min(a[x],a[x+1]),max(a[x],a[x+1])-1,0,all,1,root);
        modify(min(a[x-1],a[x]),max(a[x-1],a[x])-1,0,all,1,root);
        printf("%d\n",query(1,all-1,0,all,root));
    }
    return 0;
}

标签:return,cur,val,rs,int,Number,CF1270H,Components,leqslant
来源: https://www.cnblogs.com/lhm-/p/14322056.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有