(来源:XJ高质量原创题)

原题地址

弱化版:CF526F Pudding Monsters

弱化版

题意:\(n\times n\) 的棋盘上有 \(n\) 颗棋子,每行每列都有且仅有一颗棋子,求出有多少个 \(k\times k\) 的子棋盘也满足每行每列只有一颗棋子。

将棋盘的 \(x\) 轴看作上一题中每个点的下标,\(y\) 轴看作这个点的权值。

其实就是树退化为了链,而 \(m=1\) 的情况。

题意

给定一棵树,每一个点有一个权值 \(a_i\) ,\(\{a\}\) 构成一个排列。

询问有多少个点集 \(S={u_1,u_2,\dots,u_k}(1\le j\le n)\) 满足这些点构成联通块不超过 \(m\) 个,且 \(\max_{1\le i\le k}\{a_{u_{i}}\}-\min_{1\le i\le k}\{a_{u_{i}}\}+1=k\) 。

\(n\le 10^5,m\le 7\)

题解

考虑枚举值域的右端点 \(r\),考虑加入这个右端点时,对与 \([1,r-1]\) 中的最短点的联通块个数的变化。

先假设假设这个点与其他无边相连,那么联通块数加 \(1\) 。

对于每一条与点集中的点相连的边 \((num(r),ver)\) ,都会使左端点在 \([1,val(ver)]\) 中的联通块数量 \(-1\) (\(num(x)\) 表示权值为 \(x\) 的点的编号)。

之后我们就将题意简化为:

  • 区间加上一个数

  • 求出整个数列中 \(\le m\) 的数有多少个

  • 保证 \(a[1]=1\)

考虑到 \(m\) 比较小,猜测答案复杂度为 \(O(nm\log n)\) 。

我们将加减操作同普通的线段树操作,主要改变 \(\text{pushup}\) 操作。

在线段树的每一个节点 \([l,r]\) 上维护:

  • \(minn\) : 表示在 \([l,r]\) 区间上数的最小值。

  • \(cnt[7]\) : 表示这段区间内值域在 \([minn,minn+6]\) 之间的数分别有多少。

之后根据两个子区间的最小值就可以愉快地转移啦!!

// Author:A weak man named EricQian
// expect : 100 pts
#include<bits/stdc++.h>
using namespace std;
#define infll 0x7f7f7f7f7f7f7f7f
#define inf 0x3f3f3f3f
#define Maxn 500005
#define Maxm 7
typedef long long ll;
inline int rd()
{
int x=0;
char ch,t=0;
while(!isdigit(ch = getchar())) t|=ch=='-';
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return x=t?-x:x;
}
int n,m,tot;
int val[Maxn],num[Maxn];
int hea[Maxn],nex[Maxn<<1],ver[Maxn<<1];
struct TREE { ll minn,laz,cnt[Maxm]; }tree[Maxn<<2];
ll ans;
inline void add(int x,int y){ ver[++tot]=y,nex[tot]=hea[x],hea[x]=tot; }
inline void pushup(int p)
{
int x=p<<1,y=p<<1|1,tmp;
if(tree[x].minn>tree[y].minn) swap(x,y);
tree[p].minn=tree[x].minn;
for(int i=0;i<m;i++) tree[p].cnt[i]=tree[x].cnt[i];
tmp=tree[y].minn-tree[x].minn;
for(int i=tmp;i<m;i++) tree[p].cnt[i]+=tree[y].cnt[i-tmp];
}
inline void pushdown(int p)
{
tree[p<<1].laz+=tree[p].laz,tree[p<<1].minn+=tree[p].laz;
tree[p<<1|1].laz+=tree[p].laz,tree[p<<1|1].minn+=tree[p].laz;
tree[p].laz=0;
}
void build(int p,int nl,int nr)
{
if(nl==nr) { tree[p].minn=tree[p].cnt[0]=1; return; }
int mid=(nl+nr)>>1;
build(p<<1,nl,mid),build(p<<1|1,mid+1,nr);
pushup(p);
}
void add(int p,int nl,int nr,int l,int r,int k)
{
if(nl>=l && nr<=r) { tree[p].minn+=k,tree[p].laz+=k; return; }
pushdown(p);
int mid=(nl+nr)>>1;
if(mid>=l) add(p<<1,nl,mid,l,r,k);
if(mid<r) add(p<<1|1,mid+1,nr,l,r,k);
pushup(p);
}
int main()
{
n=rd(),m=rd();
for(int i=1;i<=n;i++) val[i]=rd(),num[val[i]]=i;
for(int i=1,x,y;i<n;i++) x=rd(),y=rd(),add(x,y),add(y,x);
build(1,1,n);
for(int r=1;r<=n;r++)
{
if(r!=1) add(1,1,n,1,r-1,1);
for(int i=hea[num[r]];i;i=nex[i])
if(val[ver[i]]<val[num[r]])
add(1,1,n,1,val[ver[i]],-1);
for(int i=0;i<m;i++) ans+=tree[1].cnt[i];
ans-=(n-r);
}
printf("%lld\n",ans);
return 0;
}

【做题记录】max-min+1=len 区间计数的更多相关文章

  1. 退役II次后做题记录

    退役II次后做题记录 感觉没啥好更的,咕. atcoder1219 历史研究 回滚莫队. [六省联考2017]组合数问题 我是傻逼 按照组合意义等价于\(nk\)个物品,选的物品\(\mod k\) ...

  2. FJOI2017前做题记录

    FJOI2017前做题记录 2017-04-15 [ZJOI2017] 树状数组 问题转化后,变成区间随机将一个数异或一,询问两个位置的值相等的概率.(注意特判询问有一个区间的左端点为1的情况,因为题 ...

  3. Sam做题记录

    Sam做题记录 Hihocoder 后缀自动机二·重复旋律5 求一个串中本质不同的子串数 显然,答案是 \(\sum len[i]-len[fa[i]]\) Hihocoder 后缀自动机三·重复旋律 ...

  4. 退役IV次后做题记录

    退役IV次后做题记录 我啥都不会了.... AGC023 D 如果所有的楼房都在\(S\)同一边可以直接得出答案. 否则考虑最左最右两边的票数,如果左边>=右边,那么最右边会投给左边,因为就算车 ...

  5. 退役III次后做题记录(扯淡)

    退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...

  6. BJOI做题记录

    BJOI做题记录 终于想起还要做一下历年省选题了2333 然而咕了的还是比做了的多2333 LOJ #2178. 「BJOI2017」机动训练 咕了. LOJ #2179. 「BJOI2017」树的难 ...

  7. UOJ 做题记录

    UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...

  8. project euler做题记录

    ProjectEuler_做题记录 简单记录一下. problem 441 The inverse summation of coprime couples 神仙题.考虑答案为: \[\begin{a ...

  9. AtCoder,Codeforces做题记录

    AGC024(5.20) 总结:猜结论,“可行即最优” B: 给定一个n的排列,每次可以将一个数移到开头或结尾,求变成1,2,...,n所需的最小步数. 找到一个最长的i,i+1,...,j满足在排列 ...

随机推荐

  1. DHCP的原理和配置

    前言 在大型企业网络中,会有大量的主机或设备需要获取IP地址等网络参数.如果采用手工配置,工作量大且不好管理,如果有用户擅自修改网络参数,还有可能会造成 IP地址冲突等问题.使用动态主机配置协议DHC ...

  2. Linux RHCE7.0 笔记(常见符号)

    1.无交互式创建用户 echo "password" | passwd --stdin username 2.Linux重定向符号 > :表示将符号左侧的内容,以覆盖的方式输 ...

  3. 浅谈VMware的NAT模式

    什么是NAT模式?理论化的措辞我就不说了,我将结合本人平时的经验来简单的说明一下NAT模式,以及配置NAT模式时遇到的问题. 大家都知道,我们的电脑要想联网,需要与交换机连接,假设交换机的网关为192 ...

  4. 5.21学习总结——android开发实现用户头像的上传

    最近在做个人头像的上传,具体是能调用摄像头和从相册进行选择.本篇文章参考的我的同学的博客,大家有兴趣可以去原作者那里去看看: Hi(.・∀・)ノ (cnblogs.com) 1.使用glide进行图片 ...

  5. 1.24学习总结——HTML常见标签

    HTML 标签简写及全称 下表列出了 HTML 标签简写及全称: 标签 英文全称 中文说明 a Anchor 锚 abbr Abbreviation 缩写词 acronym Acronym 取首字母的 ...

  6. html2canvas实现截取指定区域或iframe的区域

    官网文档: http://html2canvas.hertzen.com/ 使用的是 jquery 3.2.1   html2canvas 1.0.0-rc.7 截取根据id的指定区域: var ca ...

  7. css3 flex的IE8浏览器兼容问题

    我这是进行判断浏览器 css判断ie版本才引用样式或css文件 <!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]--> &l ...

  8. Java基础系列(11)- 变量、常量、作用域以及变量的命名规范

    变量 变量是什么:就是可以变化的量 Java是一种强类型语言,每个变量都必须声明其类型 Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域 type varName [=valu ...

  9. 通宵修复BUG的思考

    HYH.LXJ昨晚通宵修复11月版需求的bug,因为代码提到测试环境后,阻碍了一个分行进行验收测试,业务人员直接把问题反馈给了上级领导,压力下来,项目组就把问题重视起来. 对于通宵加班这件事,应该点赞 ...

  10. selenium下拉选择框处理

    HTML: (一)通过xpath层级标签定位 driver.find_element_by_xpath(".//*[@id='Resolution']/option[2]").cl ...