(来源: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. @RequestParam、@RequestBody、@PathVariable区别和案例分析

    一.前言 @RequestParam.@RequestBody.@PathVariable都是用于在Controller层接收前端传递的数据,他们之间的使用场景不太一样,今天来介绍一下!! 二.实体类 ...

  2. 【Git】给不同目录配置不同的用户名和邮箱

    场景 使用 git 时,对于公司项目和个人项目想用不同的用户名和邮箱提交,简单的解决方式就是对 git 仓库单独配置 user.name 和 user.email: 直接修改当前仓库的 .git/co ...

  3. Nginx总结(九)Nginx服务器高性能优化的配置--轻松实现10万并发访问量

    前面讲了如何配置Nginx虚拟主机,如何配置服务日志等很多基础的内容,大家可以去这里看看nginx系列文章:https://www.cnblogs.com/zhangweizhong/category ...

  4. 获取docker镜像的tag列表

    已nginx为例 命令如下 wget -q https://registry.hub.docker.com/v1/repositories/nginx/tags -O - | sed -e 's/[] ...

  5. 九、Abp vNext 基础篇丨评论聚合功能

    介绍 评论本来是要放到标签里面去讲的,但是因为上一章东西有点多了,我就没放进去,这一章单独拿出来,内容不多大家自己写写就可以,也算是对前面讲解的一个小练习吧. 相关注释我也加在代码上面了,大家看看代码 ...

  6. js根据日期获取所在周

    一.获取时间所在周的周一.周五 function getFirstLastDay (time) { let date = new Date(time) let Time = date.getTime( ...

  7. EcShop首页显示特定分类的精品新品热销特价等推荐商品

    EcShop首页显示特定分类的精品新品热销特价等推荐商品 很多大型的B2C商城都有特定分类专区,该分类下的[分类名称].[推荐子分类 或 推荐品牌].[大图片/推荐单品].[推荐商品].[促销商品]. ...

  8. ubuntu系统安装docker

    系统版本:Ubuntu 18.04 # 更新apt update # 安装依赖apt install apt-transport-https ca-certificates curl software ...

  9. Loj#2769-「ROI 2017 Day 1」前往大都会【最短路树,斜率优化】

    正题 题目链接:https://loj.ac/p/2769 题目大意 给出\(n\)个点\(m\)条地铁线路,每条线路是一条路径. 求\(1\)到\(n\)的最短路且在最短路径的情况下相邻换乘点的距离 ...

  10. 深入浅出WPF-01.WPF缘起

    WPF缘起 自2012年起,根据公司需要,开始进入界面开发工作.公司是医疗器械行业,很多操作都是基于PC进行的,所以桌面应用开发尤为重要.原有项目都是基于MFC进行的开发,而且是VC6.0的技术,维护 ...