题目链接: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 - [线段树]的更多相关文章

  1. Wannafly Winter Camp Day5 Div1 E题 Fast Kronecker Transform 转化为NTT或FFT

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门  原题目描述在最下面.  对给定的式子算解.   ...

  2. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  3. Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门  Portal  原题目描述在最下面.  简单的 ...

  4. CCPC Wannafly Winter Camp Div2 部分题解

    Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...

  5. 2020 CCPC Wannafly Winter Camp Day1 Div.1&amp F

    #include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...

  6. 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 ...

  7. 2020 CCPC Wannafly Winter Camp Day2-K-破忒头的匿名信

    题目传送门 sol:先通过AC自动机构建字典,用$dp[i]$表示长串前$i$位的最小代价,若有一个单词$s$是长串的前$i$项的后缀,那么可以用$dp[i - len(s)] + val(s)$转移 ...

  8. 2020 CCPC Wannafly Winter Camp Day1-F-乘法

    题目传送门 sol:二分答案$K$,算大于$K$的乘积有多少个.关键在于怎么算这个个数,官方题解上给出的复杂度是$O(nlogn)$,那么计算个数的复杂度是$O(n)$的.感觉写着有点困难,自己写了一 ...

  9. Wannafly Winter Camp 2020 Day 7A 序列 - 树状数组

    给定一个全排列,对于它的每一个子序列 \(s[1..p]\),对于每一个 \(i \in [1,p-1]\),给 \(s[i],s[i+1]\) 间的每一个值对应的桶 \(+1\),求最终每个桶的值. ...

随机推荐

  1. 解决 Firefox 下载文件名乱码扩展 ReDisposition

    作者 muzuiget  发布 2013-03-13 19:23  标签 redisposition Firefox 下载文件名乱码问题由来已久,偶然一两次还可以手动改名,批量下载时简直要亲命,最终我 ...

  2. ceph 生成rpm包

    概述 从ceph的源码build出rpm包: #git clone --recursive https://github.com/ceph/ceph.git #./instal-dep.sh 以上两点 ...

  3. Effective Java 第三版——50. 必要时进行防御性拷贝

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  4. SVProgressHUD在viewDidLoad里无法显示的bug

    两年前已经开始讨论,至今没有解决方案.https://github.com/samvermette/SVProgressHUD/issues/54 [SVProgressHUD show] 的逻辑要放 ...

  5. 第三部分:Android 应用程序接口指南---第二节:UI---第三章 菜单

    第3章 菜单 在许多不同类型的应用中,菜单通常是一种用户界面组件.为了提供给用户提供熟悉且一致的体验,你需要使用菜单API来展示用户动作和你Activity中的其他选项. 从安卓3.0系统(API l ...

  6. Vert.x 示例

    //filename: MainVerticle.java package io.vertx.guides.wiki; import io.vertx.core.AbstractVerticle; i ...

  7. pandas DataFrame(1)

    之前介绍了numpy的二维数组,但是numpy二维数组有一些局限性,比如,它数组里所有的值的类型必须相同,不能某一列是数值型,某一列是字符串型,这样会导致无法使用 mean() , std() 等方法 ...

  8. python os.system()和os.popen()

    1>python调用Shell脚本,有两种方法:os.system()和os.popen(),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容.>>>hel ...

  9. WebMisSharp,WebMisCentral,企业框架正则表达式规则共享专版

    ElegantWM.WebUI/Application/common/src/Tools.js 欢迎大家贡献更多的正则验证规则,目前支持如下: /*************************** ...

  10. android开发(46) 使用 textview实现文字的阴影效果,浮雕效果

    前言 最近看到一些文字的阴影效果很有意思,尝试了下,形成本文.“平面效果“是我们平时常见的平面的样子.“阴影效果”会给人一种凸起的感觉.浮雕效果会给一种雕刻“凹陷”的感觉. 演示效果图 方法 使用 t ...