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, ...
随机推荐
- go实现java虚拟机01
前段时间看了一本书,说的是用go语言实现java虚拟机,很有意思,于是就花了一段时间学习了一下go语言,虽然对go的底层理解不是很深,但是写代码还是可以的,就当做个读书笔记吧! 链接在这里,另外还有一 ...
- jquery带下拉列表的购物车组件封装
按照国际惯例先放效果图 安静的时候它长这样 等待加载时它长这样(功能是设置的按需加载,网速慢或者加载数据大时会出现) 加载之后购物车没有商品时这样 有商品长这样 接下来放代码: cart.html & ...
- 安装npm install时,长时间停留在fetchMetadata的解决方法
安装npm install时,长时间停留在fetchMetadata: sill mapToRegistry uri http://registry.npmjs.org/whatwg-fetch处, ...
- RMAN中MAXSETSIZE和MAXPIECESIZE的用法
MAXSETSIZE跟MAXPIECESIZE用法 区别:maxpiecesize设置的是备份完成后的备份片大小,对备份整体的大小没有影响,比如一个G的备份完成文件,maxpiecesize设置为10 ...
- vuex的state选项rootState.js
说明:本文做为vuex学习详细解(主页目录 配置主页:vuex学习配置详解(目录rootState.js文件如下 作用声明 vuex的state选项常量,并导出默认为state /** * 此文件除声 ...
- 用ArcGIS Runtime for Android建立简单App,展示地图
1.新建AS项目 此处引用官网上新建项目的过程,很简单,不做翻译了. 2.配置ArcGIS Runtime for Android100.5.0环境 2-1.项目切换成Project 2-2 .选择P ...
- 自动驾驶定位算法-直方图滤波(Histogram Filter)定位
1.直方图滤波(Histogram Filter)的算法思想 直方图滤波的算法思想在于:它把整个状态空间dom(x(t))切分为互不相交的部分\(b_1.b_2....,b_{n-1}\),使得: 然 ...
- centos7系统中忘记了root管理员账号密码的解决方式
随着计算机的使用越来越普遍,现在的用户都会有多个密码,不是这软件的密码就是那个的,QQ.邮箱.游戏,还有系统的登录密码!每一个密码都不一样!所以越来越多的密码需要去记住!也因为这样,只要其中一个长时间 ...
- BZOJ2005: [Noi2010]能量采集(欧拉函数)
Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后, 栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种 ...
- Mac IDEA 2019.3.1下载及破解,可激活至2089年
背景 目前IDEA已更新到2019.3.3,但是下载这个版本后使用目前网上的常见破解方法会出现各种问题.比如使用注册码方式提示license key is in legacy format,或者使用L ...