CCPC-Wannafly Winter Camp Day5 Div1 - Sorting - [线段树]
题目链接:https://zhixincode.com/contest/22/problem/I?problem_id=314
样例输入 1
5 9 3
1 5 3 2 4
1 1 5
2 1 5
1 1 1
1 2 2
1 3 3
1 4 4
1 5 5
3 3 5
1 1 4
样例输出 1
15
1
3
2
5
4
13
题解:
dls出的题真好qwq!
我们先考虑partition的两种操作,若将所有小于等于 $x$ 的数字看成 $0$,将所有大于 $x$ 的数字看成 $1$,那么原序列就变成了一个 $01$ 序列。
那么两种partition操作,就相当于将某个区间内的所有 $0$ 放到一边,所有 $1$ 放到另一边。这个操作就很简单,我们可以 $O(\log n)$ 统计出该区间内有多少个 $0$ 以及多少个 $1$,然后相应的将区间的左边一段赋值成 $0$(或者 $1$),将区间右边一段赋值成 $1$(或者 $0$)。
然后,对于求和操作:
首先不难发现,不管怎么操作,对于所有小于等于 $x$ 的数字来说,它们之间的顺序是不会改变的;同样对于所有大于 $x$ 的数字,它们之间的顺序也不会改变。因此,对于任意一个位置,假设该位置上是一个 $0$,那么只要统计这个位置左侧有几个 $0$ 就可以知道,这个位置对应到原序列是什么数字。当然,我们若是对区间内每个位置都这样去求出是多少,再求和,显然时间复杂度是比较差的。
因此,我们可以根据前缀和的思想,对于要求和的区间 $[l,r]$,我们可以 $O(\log n)$ 统计出 $[1,l-1]$ 和 $[1,r]$ 各有多少个 $0$,然后我们就知道了 $[l,r]$ 区间对应到原序列是哪个区间,然后原序列做一下前缀和求差值即可得到答案。类似的,统计 $1$ 的数目也是这样一个道理。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+; int n,q,x,v[maxn];
int tota,totb;
ll a[maxn],b[maxn]; #define ls (rt<<1)
#define rs (rt<<1|1)
struct Node{
int l,r;
int val,lazy;
void update(int x)
{
val=(r-l+)*x;
lazy=x;
}
}o[maxn<<];
void pushdown(int rt)
{
if(o[rt].lazy==-) return;
o[ls].update(o[rt].lazy);
o[rs].update(o[rt].lazy);
o[rt].lazy=-;
}
inline void pushup(int rt)
{
o[rt].val=o[ls].val+o[rs].val;
}
void build(int rt,int l,int r)
{
o[rt].l=l, o[rt].r=r;
o[rt].lazy=-;
if(l==r)
{
o[rt].val=(v[l]>x);
return;
}
int mid=(l+r)>>;
build(ls,l,mid);
build(rs,mid+,r);
pushup(rt);
}
void update(int rt,int st,int ed,int val)
{
if(st<=o[rt].l && o[rt].r<=ed)
{
o[rt].update(val);
return;
}
pushdown(rt);
int mid=(o[rt].l+o[rt].r)>>;
if(st<=mid) update(ls,st,ed,val);
if(mid<ed) update(rs,st,ed,val);
pushup(rt);
}
int query(int rt,int st,int ed)
{
if(st>ed) return ;
if(st<=o[rt].l && o[rt].r<=ed) return o[rt].val;
pushdown(rt);
int mid=(o[rt].l+o[rt].r)>>, res=;
if(st<=mid) res+=query(ls,st,ed);
if(mid<ed) res+=query(rs,st,ed);
pushup(rt);
return res;
} int main()
{
ios::sync_with_stdio();
cin.tie(), cout.tie(); cin>>n>>q>>x; tota=totb=, a[]=b[]=;
for(int i=;i<=n;i++)
{
cin>>v[i]; //按x拆分序列并求前缀和
if(v[i]<=x) a[++tota]=a[tota-]+v[i];
if(v[i]>x) b[++totb]=b[totb-]+v[i];
} build(,,n);
while(q--)
{
int t,l,r; cin>>t>>l>>r;
if(t==)
{
int r_cnt1=query(,,r), r_cnt0=(r-+)-r_cnt1;
int l_cnt1=query(,,l-), l_cnt0=((l-)-+)-l_cnt1;
cout<<(a[r_cnt0]-a[l_cnt0])+(b[r_cnt1]-b[l_cnt1])<<'\n';
}
if(t==)
{
int cnt1=query(,l,r), cnt0=(r-l+)-cnt1;
update(,l,l+cnt0-,), update(,r-cnt1+,r,);
}
if(t==)
{
int cnt1=query(,l,r), cnt0=(r-l+)-cnt1;
update(,l,l+cnt1-,), update(,r-cnt0+,r,);
}
}
}
CCPC-Wannafly Winter Camp Day5 Div1 - Sorting - [线段树]的更多相关文章
- Wannafly Winter Camp Day5 Div1 E题 Fast Kronecker Transform 转化为NTT或FFT
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门 原题目描述在最下面. 对给定的式子算解. ...
- 2020 CCPC Wannafly Winter Camp Day1 C. 染色图
2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...
- Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门 Portal 原题目描述在最下面. 简单的 ...
- CCPC Wannafly Winter Camp Div2 部分题解
Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...
- 2020 CCPC Wannafly Winter Camp Day1 Div.1& F
#include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...
- 2020 CCPC Wannafly Winter Camp Day1 - I. K小数查询(分块)
题目链接:K小数查询 题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种: 输入$x,y,c$,表示对$i\in[x,y] $,令$A_{i}=min(A_{i},c)$ 输入$x,y ...
- 2020 CCPC Wannafly Winter Camp Day2-K-破忒头的匿名信
题目传送门 sol:先通过AC自动机构建字典,用$dp[i]$表示长串前$i$位的最小代价,若有一个单词$s$是长串的前$i$项的后缀,那么可以用$dp[i - len(s)] + val(s)$转移 ...
- 2020 CCPC Wannafly Winter Camp Day1-F-乘法
题目传送门 sol:二分答案$K$,算大于$K$的乘积有多少个.关键在于怎么算这个个数,官方题解上给出的复杂度是$O(nlogn)$,那么计算个数的复杂度是$O(n)$的.感觉写着有点困难,自己写了一 ...
- Wannafly Winter Camp 2020 Day 7A 序列 - 树状数组
给定一个全排列,对于它的每一个子序列 \(s[1..p]\),对于每一个 \(i \in [1,p-1]\),给 \(s[i],s[i+1]\) 间的每一个值对应的桶 \(+1\),求最终每个桶的值. ...
随机推荐
- VisualVM、JConsole
VisualVM.JConsole 需要熟悉JVM内存模型 https://blog.csdn.net/libaolin198706231987/article/details/55057149 ht ...
- 去除移动端alert/confirm的网址(url)
移动端的alert.confirm都会显示来源的url,影响体验 下面的代码将alert和confirm重写了一遍,可去除url 参考了网上代码,完善了confirm不同状态跳转 示例代码: & ...
- CentOS 7 安装SVN服务端
CentOS7下安装SVN服务 1. yum命令即可方便的完成安装# sudo yum install subversion 测试安装是否成功:# svnserve --version 更改svn的默 ...
- 引导修复软件boot-repair
因为经常需要安装双系统win10+ubuntu,平时按照先win10,在ubuntu的顺序,是非常顺利的,grub非常智能也非常友好的帮助你双启动这2个系统. 但是,难免会有意外,比如,win10有了 ...
- 判断一棵二叉树是否为AVL树
思路:AVL树是高度平衡的二叉搜索树,这里为了清晰说明,分别判断是否为搜索树,是否为平衡树. struct TreeNode { struct TreeNode *left; struct TreeN ...
- 【Linux高级驱动】linux设备驱动模型之平台设备驱动机制
[1:引言: linux字符设备驱动的基本编程流程] 1.实现模块加载函数 a.申请主设备号 register_chrdev(major,name,file_operations); b.创 ...
- Go Revel - i18n(国际化)
##Messages `Messages`信息是对内容提供翻译的外部文本片段.revel提供了组织每一种语言文本片段的message文件.自动区域查找.基于cookie覆盖的消息嵌套和参数. 术语表: ...
- maven 打jar 被引用后 出现 cannot resolve symbol 错误 生成jar包形式代码文件组织格式 非springboot文件组织格式
项目A引用项目B A项目中pom引入没有报错,但是:1,idea里面查找到b项目中的代码时,会提示b代码中的引用不正确.提示无法解析语法 解压B的jar,发现目录是: springboot文件组织格式 ...
- Java知多少(中)
Java知多少(上) )interface接口 )接口和抽象类的区别 )泛型详解 )泛型通配符和类型参数的范围 )异常处理基础 )异常类型 )未被捕获的异常 )try和catch的使用 )多重catc ...
- CLOS网络架构与FATTREE胖树拓扑
FatTree拓扑结构是由MIT的Fares等人在改进传统树形结构性能的基础上提出的,属于switch-only型拓扑. 整个拓扑网络分为三个层次:自上而下分别为边缘层(edge).汇聚层(aggre ...