题目大意:给出一个n个元素的数组A,A中所有元素都是不重复的[1,n]。
有两种操作:
1.将pos位置的元素+1e7
2.查询不属于[1,r]中的最小的>=k的值。
强制在线。

题解
因为数组中的值唯一,且在1到n的范围内,而询问的r和k也在1到n的范围内。 所以对于任意一个被操 作1修改过的值都不会成为询问的答案,而询问的结果也必然在k到n+1的范围内。 因为没有被修改过 值是唯一的,所以可以建立权值线段树,维护权值区间内的值所在下标的最大值。而询问则转化为不小 于k的值里面,下标超过r的最小权值是多少。 如何处理询问呢,一种较为暴力的解法是直接在线段树上 询问权值在k到n+1的范围内第一个下标超过r的权值是多少。但复杂度可能会被卡,需要减枝。 再加上 一个额外的判断就可以了,就是在递归查询完左子树内存不存在大于r的下标之后,如果不存在,则先 看一下右子树内的下标的最大值是否大于r。如果不大于r,则不必再进入右子树内查询,否则答案一定 在右子树内。在进左子树之前也利用同样的判断条件来判断是否有必要进入左子树,这样做可以保证单 次查询的复杂度是O(log n) 的。 而对于操作1,则等价于修改某个权值的下标为无穷大。操作复杂度也 是O(log n )的。 综上所述,得到了一个复杂度为O( m * log n )的在线算法,可以较快地通过此题。

/*HDU 6703 array
权值线段树 在线处理
2019/08/27 12:00
*/
#pragma GCC optimize(3,"Ofast","inline") //G++
#pragma comment(linker, "/STACK:102400000,102400000")
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include <functional>
#define TEST freopen("in.txt","r",stdin);
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull; // %llu
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod=1e9+;
const int INF = 1e6+;
const int maxn = 1e5+;
int n,q;
struct node
{
int l,r,pos; //建立权值线段树 维护区间下标最大值
} t[*maxn];
int a[maxn];
void build(int l,int r,int o) //一颗大树由此而生
{
t[o].l=l;
t[o].r=r;
if(l==r)
{
return ;
}
int mid=(l+r)>>;
build(l,mid,o<<);
build(mid+,r,o<<|);
}
void pushup(int o) //自如其名 pushup
{
t[o].pos=max(t[o<<].pos,t[o<<|].pos);
}
void add(int o,int x,int pos) //添加操作 维护区间下标最大值
{
if(t[o].l==t[o].r&&t[o].l==x)
{
t[o].pos=pos;
return ;
}
int mid=(t[o].l+t[o].r)>>;
if(x<=mid)
add(o<<,x,pos);
else
add(o<<|,x,pos);
pushup(o);
}
int qurey(int o,int l,int r,int ask)
{
if(t[o].l==t[o].r) //到叶子节点判读答案是否成立
{
if(t[o].pos>ask)
return t[o].l;
else
return INF;
}
if(t[o].l==l&&t[o].r==r) //在当期节点区间时 需要根据左右子树的pos值判读下一步往哪边走(剪枝)
{
if(t[o<<].pos>ask)
{
return qurey(o<<,l,(l+r)>>,ask);
}
else if(t[o<<|].pos>ask)
{
return qurey(o<<|,(l+r)>>|,r,ask);
}
else
return INF;
}
int mid=(t[o].l+t[o].r)>>; //熟悉的操作
if(r<=mid)
{
return qurey(o<<,l,r,ask); //锁定区间
}
else if(l>mid)
{
return qurey(o<<|,l,r,ask); //还是锁定区间
}
else
{
return min(qurey(o<<,l,mid,ask),qurey(o<<|,mid+,r,ask)); //锁定区间 答案即可能在左子树也可能在右子树 所以取左右子树中最小的值(有可能左子树返回INF)
}
}
void init() //输入
{ scanf("%d%d",&n,&q);
build(,+n,);
for(int i=; i<=n; i++)
{
scanf("%d",&a[i]);
add(,a[i],i);
}
add(,n+,INF);
}
void solve() //解决
{
int op,last=; //在线处理
while(q--)
{
scanf("%d",&op);
if(op==)
{
int pos;
scanf("%d",&pos);
pos^=last;
add(,a[pos],INF);
}
else
{
int r,k;
scanf("%d%d",&r,&k);
r^=last,k^=last;
last=qurey(,k,n+,r);
printf("%d\n",last);
}
}
}
int main()
{
// TEST
int T;
scanf("%d",&T);
while(T--)
{
mem(t,);
init();
solve();
}
}

2019年CCPC网络赛 HDU 6703 array【权值线段树】的更多相关文章

  1. hdu 6703 array(权值线段树)

    Problem Description You are given an array a1,a2,...,an(∀i∈[1,n],1≤ai≤n). Initially, each element of ...

  2. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

  3. 2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)

    HDU 5489 Removed Interval 题意: 求序列中切掉连续的L长度后的最长上升序列 思路: 从前到后求一遍LIS,从后往前求一遍LDS,然后枚举切开的位置i,用线段树维护区间最大值, ...

  4. 2015上海网络赛 HDU 5475 An easy problem 线段树

    题意就不说了 思路:线段树,维护区间乘积.2操作就将要除的点更新为1. #include<iostream> #include<cstdio> #include<cstr ...

  5. Petya and Array (权值线段树+逆序对)

    Petya and Array http://codeforces.com/problemset/problem/1042/D time limit per test 2 seconds memory ...

  6. HDU 6609 离散化+权值线段树

    题意 有一个长度为\(n\)的数组W; 对于每一个\(i\)(\(1<=i<=n\)),你可以选择中任意一些元素W[k] (\(1<=k<i\)),将他们的值改变为0,使得\( ...

  7. ccpc 网络赛 hdu 6155

    # ccpc 网络赛 hdu 6155(矩阵乘法 + 线段树) 题意: 给出 01 串,要么询问某个区间内不同的 01 子序列数量,要么把区间翻转. 叉姐的题解: 先考虑怎么算 \(s_1, s_2, ...

  8. ccpc网赛 hdu6703 array(权值线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=6703 大意:给一个n个元素的数组,其中所有元素都是不重复的[1,n]. 两种操作: 将pos位置元素+1e7 查 ...

  9. HDU 6464 免费送气球 【权值线段树】(广东工业大学第十四届程序设计竞赛)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6464 免费送气球 Time Limit: 2000/1000 MS (Java/Others)    M ...

随机推荐

  1. 关于android工具链

    1 android sdk platform tools 同android platform交互的工具,包括adb.fastboot和systrace. 2 sdk build tools 用于bui ...

  2. Java Mail 附件名太长导致接收端附件名解析出错

    问题前提:公司需要往邮件中写 excle 文件,返送成功后发现文件格式有误(如:xxxx.bat 等文件后缀),但是有些文件又不会, 后来发现是由于文件名称太长所导致. 问题原因:java mail中 ...

  3. Linux下配置JDK环境

    安装前需要查询Linux中是否已经存在jdk 如果存在,将存在的jdk删除 在/etc/profile中添加以下 JAVA_HOME为jdk的安装目录 PATH为jdk可执行文件的目录 使用sourc ...

  4. javaweb新手学习之Tomcat

    一.Tomcat服务器常见启动问题: (1).Java_home环境变量,由于tomcat服务器的bin目录中的一些jar文件必须使用到java类库,所以必须先配置Java_home环境变量. (2) ...

  5. MongoDB的使用学习之(五)Spring集成MongoDB以及简单的CRUD

    这篇文章不错:Spring Data - MongoDB 教程 (1.0.0.M1)http://miller-cn.iteye.com/blog/1258859 1.介绍 之前在很多地方一直见到这个 ...

  6. django基础篇06-ModelForm操作及验证

    本文内容主要来自银角大王的博客 学习大纲: 一.ModelForm 二.Ajax - 原生(jQuery) - 伪Ajax操作 三.文件上传(预览) - Form提交 - Ajax文件上传 四. 图片 ...

  7. C# wpf 列出文件夹所有文件

    在网上找了 cmd输入 dir "要列出的文件夹*.*" /a /b /s>"要输出的文件" 可以重定向把文件夹内容输出到文件 tree "要列 ...

  8. java程序员究竟应该掌握点什么

    JAVA程序设计(基础部分) JAVA程序设计(专题)

  9. rest_framework框架的认证、权限

    REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth", ] ...

  10. MIT-线性代数公开课

    本博客是学习MIT-线性代数笔记,Gilbert Strang大神讲的通俗易懂,感兴趣的可以观看视频 其中习题集请点击 01)方程组的几何解释 02)矩阵消元 03)乘法和逆矩阵 04)A的LU分解 ...