Wannafly Camp 2020 Day 1I K小数查询 - 分块
给你一个长度为\(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小数查询 - 分块的更多相关文章
- 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 ...
- Wannafly Winter Camp 2020 Day 6J K重排列 - dp
求 \(K\) 是多少个 \(n\) 元置换的周期.\(T\leq 100, n\leq 50, K \leq 10^{18}\) Solution 置换可以被试做若干个环组成的有向图,于是考虑 dp ...
- Wannafly Camp 2020 Day 3I N门问题 - 概率论,扩展中国剩余定理
有一个猜奖者和一个主持人,一共有 \(n\) 扇门,只有一扇门后面有奖,主持人事先知道哪扇门后有奖,而猜奖者不知道.每一轮,猜奖者选择它认为的有奖概率最大(如果有多个最大,随机选一个)的一扇门,主持人 ...
- Wannafly Camp 2020 Day 3F 社团管理 - 决策单调性dp,整体二分
有 \(n\) 个数构成的序列 \({a_i}\),要将它划分为 \(k\) 段,定义每一段的权值为这段中 \((i,j) \ s.t. \ i<j,\ a_i=a_j\) 的个数,求一种划分方 ...
- 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 ...
- Wannafly Camp 2020 Day 1D 生成树 - 矩阵树定理,高斯消元
给出两幅 \(n(\leq 400)\) 个点的无向图 \(G_1 ,G_2\),对于 \(G_1\) 的每一颗生成树,它的权值定义为有多少条边在 \(G_2\) 中出现.求 \(G_1\) 所有生成 ...
- Wannafly Camp 2020 Day 2I 堡堡的宝藏 - 费用流
感谢这道题告诉我KM求的是 完备 最大权匹配 :( #include <bits/stdc++.h> using namespace std; #define reset(x) memse ...
- Wannafly Camp 2020 Day 1C 染色图 - 组合数学,整除分块
定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任何一条边 (u,v),都有 f(u)≠f(v). 定义函数 g(n,k) 的值为所有包 ...
- Wannafly Camp 2020 Day 6M 自闭 - 模拟
按题意模拟,又乱又烦,没什么可说的 #include <bits/stdc++.h> using namespace std; #define int long long int n,m, ...
随机推荐
- 题解【[USACO05NOV]奶牛玩杂技】
\[ \texttt{Description} \] 有 \(n\) 头牛,每头牛都有自己的体重 \(W_i\) 和力量 \(S_i\) . 将这 \(n\) 头牛摞在一起,每头牛的压扁指数定义为:压 ...
- XAML 字符转义
在 写xaml的使用遇到了一些特殊字符,这里记录一下特殊字符转义. 这些特殊字符遵循用于编码的万维网联合会(W3C) XML 标准. 下表显示这组特殊字符的编码语法: 字符 语法 描述 < & ...
- maven导入sqlserver驱动jar包依赖包到本地仓库
maven导入sqlserver驱动jar包依赖包到本地仓库 maven项目使用sqlserver的依赖,先下载一个sqlserver的驱动,网址:https://www.microsoft.com/ ...
- AGC018F - Two Trees
题意 有两棵节点数均为 n 的有根树,你需要构造一个序列 \(X_1,X_2,...,X_n\).使得对于每一棵树的每一个节点, 若令它所有的后代(包括它本身)为 \(a_1,a_2,...,a_k\ ...
- java提取字符串数字,Java获取字符串中的数字
================================ ©Copyright 蕃薯耀 2020-01-17 https://www.cnblogs.com/fanshuyao/ 具体的方法如 ...
- C# WPF聊天界面(3/3)
微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# WPF聊天界面(3/3) 阅读导航 本文背景 代码实现 本文参考 1.本文背景 系列文章 ...
- 《茶余饭后小故事》MV*、MVC、MVP、MVVM的前世今生
今天我们讲讲历史,讲讲故事,不扯高深术语. MV*表示的意思是:M(Model逻辑层) + View(视图层) + *(中间者).上帝提出了这个逻辑与视图分离,用中间者进行连接的伟大思想,并将实现这个 ...
- UTF-8(bom-non)
Public Sub WriteUTF_8BomNon(ByVal fileName As String, ByVal strLine As String) Dim stream: Set strea ...
- SVN使用经验
转载于:Svn发布项目 个人使用体验: 关于svn的相关命令 从服务器检出创建的项目文件夹,向项目中添加文件,右键tortoiseSvn->add 然后右键SVN Commit,选择文件并输入提 ...
- CF594D REQ [离线+树状数组,欧拉函数]
设 \[x = \prod_{i=1}^{cnt} p_i^{k_i} [p_i\in prime]\] 那么显然 \[\varphi(x) = x*\frac{1} {\prod_{i=1}^{cn ...