给你一个长度为\(n\)序列\(A\),有\(m\)个操作,操作分为两种:

  • 输入\(x,y,c\),表示对\(i\in[x,y]\),令\(A_{i}=min(A_{i},c)\)
  • 输入\(x,y,k\),表示询问区间 \([x,y]\) 中的第\(k\)小数

Solution

考虑分块,块内排序,同时记录这一块被整体取过的 \(min\) 的最小值

对于修改,对不完整的块,我们直接暴力在原序列上修改然后重建块,标记不动

对完整的块,只修改标记

这样修改的时间复杂度为 \(O(k \log k)\),其中 \(k\) 为块大小

对于询问,我们二分答案,考虑检验,在每个完整的块上统计需要检查标记,如果标记比当前枚举的值小则直接计数,否则在块上再次二分;对于不完整的块,检查标记并在序列上暴力查询即可。查询时间复杂度的宽界为 \(O(\frac{n}{k} \log k \log V)\)

求解根号平衡,\(k = \frac{n}{k} \log V\),得 \(k = \sqrt{n \log V}\),考虑到 \(V \leq 10^9\),取 \(k=\sqrt{30n}\) ,实际上由于常数问题,\(k\)取 \(\sqrt{3n}\) 即可

#include <bits/stdc++.h>
using namespace std; const int N = 1005;
const int inf = 1e+9+7;
vector <int> b[N];
int n, m, a[N*N], bel[N*N], bl[N], br[N], tag[N], K, tot; void build() {
K = sqrt(3*n);
for(int i=1;i<=n;i++) bel[i] = i/K+1;
for(int i=1;i<=n;i++) br[bel[i]]=i;
for(int i=n;i>=1;i--) bl[bel[i]]=i;
for(int i=1;i<=n;i++) b[bel[i]].push_back(a[i]);
for(int i=1;i<=n;i++) tot = max(tot,bel[i]);
for(int i=1;i<=tot;i++) tag[i] = inf;
for(int i=1;i<=tot;i++) sort(b[i].begin(), b[i].end());
} void modify_part(int l,int r,int x) {
int id = bel[l];
for(int i=l;i<=r;i++) a[i] = min(a[i],x);
b[id].clear();
for(int i=bl[id];i<=br[id];i++) b[id].push_back(a[i]);
sort(b[id].begin(), b[id].end());
} void modify(int l,int r,int x) {
for(int i=bel[l]+1;i<bel[r];i++) tag[i] = min(tag[i],x);
if(bel[l] == bel[r]) { // !!
modify_part(l, r, x);
}
else {
modify_part(l, br[bel[l]], x);
modify_part(bl[bel[r]], r, x);
}
} int check_part(int l,int r,int x) {
if(tag[bel[l]]<=x) return r-l+1;
int ans = 0;
for(int i=l;i<=r;i++) ans += a[i]<=x?1:0;
return ans;
} int check_block(int i,int x) {
if(tag[i]<=x) return br[i]-bl[i]+1;
return upper_bound(b[i].begin(),b[i].end(),x) - b[i].begin();
} int check(int l,int r,int x) {
int ans = 0;
for(int i=bel[l]+1;i<bel[r];i++) ans += check_block(i,x);
if(bel[l]==bel[r]) { // !!
ans = check_part(l, r, x);
}
else {
ans += check_part(l, br[bel[l]], x);
ans += check_part(bl[bel[r]], r, x);
}
return ans;
} int query(int ql,int qr,int k) {
int l=1, r=1e9+1;
while(l<r) {
int mid = (l+r)/2;
if(check(ql,qr,mid) < k) l=mid+1;
else r=mid;
}
return l;
} int main() {
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build();
for(int i=1;i<=m;i++) {
int t1,t2,t3,t4;
cin>>t1>>t2>>t3>>t4;
if(t1==1) {
modify(t2,t3,t4);
}
if(t1==2) {
cout<<query(t2,t3,t4)<<endl;
}
}
}

Wannafly Camp 2020 Day 1I K小数查询 - 分块的更多相关文章

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

  2. Wannafly Winter Camp 2020 Day 6J K重排列 - dp

    求 \(K\) 是多少个 \(n\) 元置换的周期.\(T\leq 100, n\leq 50, K \leq 10^{18}\) Solution 置换可以被试做若干个环组成的有向图,于是考虑 dp ...

  3. Wannafly Camp 2020 Day 3I N门问题 - 概率论,扩展中国剩余定理

    有一个猜奖者和一个主持人,一共有 \(n\) 扇门,只有一扇门后面有奖,主持人事先知道哪扇门后有奖,而猜奖者不知道.每一轮,猜奖者选择它认为的有奖概率最大(如果有多个最大,随机选一个)的一扇门,主持人 ...

  4. Wannafly Camp 2020 Day 3F 社团管理 - 决策单调性dp,整体二分

    有 \(n\) 个数构成的序列 \({a_i}\),要将它划分为 \(k\) 段,定义每一段的权值为这段中 \((i,j) \ s.t. \ i<j,\ a_i=a_j\) 的个数,求一种划分方 ...

  5. Wannafly Camp 2020 Day 2B 萨博的方程式 - 数位dp

    给定 \(n\) 个数 \(m_i\),求 \((x_1,x_2,...,x_n)\) 的个数,使得 \(x_1 \ xor\ x_2\ xor\ ...\ xor\ x_n = k\),且 \(0 ...

  6. Wannafly Camp 2020 Day 1D 生成树 - 矩阵树定理,高斯消元

    给出两幅 \(n(\leq 400)\) 个点的无向图 \(G_1 ,G_2\),对于 \(G_1\) 的每一颗生成树,它的权值定义为有多少条边在 \(G_2\) 中出现.求 \(G_1\) 所有生成 ...

  7. Wannafly Camp 2020 Day 2I 堡堡的宝藏 - 费用流

    感谢这道题告诉我KM求的是 完备 最大权匹配 :( #include <bits/stdc++.h> using namespace std; #define reset(x) memse ...

  8. Wannafly Camp 2020 Day 1C 染色图 - 组合数学,整除分块

    定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任何一条边 (u,v),都有 f(u)≠f(v). 定义函数 g(n,k) 的值为所有包 ...

  9. Wannafly Camp 2020 Day 6M 自闭 - 模拟

    按题意模拟,又乱又烦,没什么可说的 #include <bits/stdc++.h> using namespace std; #define int long long int n,m, ...

随机推荐

  1. 题解【[USACO05NOV]奶牛玩杂技】

    \[ \texttt{Description} \] 有 \(n\) 头牛,每头牛都有自己的体重 \(W_i\) 和力量 \(S_i\) . 将这 \(n\) 头牛摞在一起,每头牛的压扁指数定义为:压 ...

  2. XAML 字符转义

    在 写xaml的使用遇到了一些特殊字符,这里记录一下特殊字符转义.  这些特殊字符遵循用于编码的万维网联合会(W3C) XML 标准. 下表显示这组特殊字符的编码语法: 字符 语法 描述 < & ...

  3. maven导入sqlserver驱动jar包依赖包到本地仓库

    maven导入sqlserver驱动jar包依赖包到本地仓库 maven项目使用sqlserver的依赖,先下载一个sqlserver的驱动,网址:https://www.microsoft.com/ ...

  4. AGC018F - Two Trees

    题意 有两棵节点数均为 n 的有根树,你需要构造一个序列 \(X_1,X_2,...,X_n\).使得对于每一棵树的每一个节点, 若令它所有的后代(包括它本身)为 \(a_1,a_2,...,a_k\ ...

  5. java提取字符串数字,Java获取字符串中的数字

    ================================ ©Copyright 蕃薯耀 2020-01-17 https://www.cnblogs.com/fanshuyao/ 具体的方法如 ...

  6. C# WPF聊天界面(3/3)

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# WPF聊天界面(3/3) 阅读导航 本文背景 代码实现 本文参考 1.本文背景 系列文章 ...

  7. 《茶余饭后小故事》MV*、MVC、MVP、MVVM的前世今生

    今天我们讲讲历史,讲讲故事,不扯高深术语. MV*表示的意思是:M(Model逻辑层) + View(视图层) + *(中间者).上帝提出了这个逻辑与视图分离,用中间者进行连接的伟大思想,并将实现这个 ...

  8. UTF-8(bom-non)

    Public Sub WriteUTF_8BomNon(ByVal fileName As String, ByVal strLine As String) Dim stream: Set strea ...

  9. SVN使用经验

    转载于:Svn发布项目 个人使用体验: 关于svn的相关命令 从服务器检出创建的项目文件夹,向项目中添加文件,右键tortoiseSvn->add 然后右键SVN Commit,选择文件并输入提 ...

  10. CF594D REQ [离线+树状数组,欧拉函数]

    设 \[x = \prod_{i=1}^{cnt} p_i^{k_i} [p_i\in prime]\] 那么显然 \[\varphi(x) = x*\frac{1} {\prod_{i=1}^{cn ...