权值线段树模板题

array
Time Limit: 1500ms Memory Limit: 256M Description
You are given an array . Initially, each element of the array is unique.
Moreover, there are  instructions. Each instruction is in one of the following two formats: 1. ,indicating to change the value of  to ; 2. ,indicating to ask the minimum value which is not equal to any  (  ) and not less than . Please print all results of the instructions in format .
Input
The ?rst line of the input contains an integer , denoting the number of test cases. In each test case, there are two integers , in the ?rst line, denoting the size of array  and the number of instructions.
In the second line, there are  distinct integers  ,denoting the array. For the following  lines, each line is of format  or . The parameters of each instruction are generated by such way : For instructions in format  , we de?ned  . (It is promised that )
For instructions in format  , we de?ned . (It is promised that  ) (Note that  means the bitwise XOR operator. ) Before the ?rst instruction of each test case,  is equal to  .After each instruction in format ,  will be changed to the result of that instruction.
( ) Output
For each instruction in format , output the answer in one line. Sample Input
3 5 9
4 3 1 2 5 2 1 1 2 2 2
2 6 7 2 1 3 2 6 3
2 0 4 1 5
2 3 7 2 4 3 10 6
1 2 4 6 3 5 9 10 7 8 2 7 2
1 2 2 0 5 2 11 10
1 3 2 3 2
10 10 9 7 5 3 4 10 6 2 1 8
1 10 2 8 9 1 12
2 15 15 1 12
2 1 3 1 9 1 12
2 2 2 1 9 Sample Output
1 5
2 2
5 6 1
6 7
3 11 10
11 4
8 11 [hint] note: After the generation procedure ,the instructions of the ?rst test case are : 2 1 1, in format 2 and r=1 , k=1 2 3 3, in format 2 and r=3 , k=3 2 3 2, in format 2 and r=3 , k=2 2 3 1, in format 2 and r=3 , k=1 2 4 1, in format 2 and r=4 , k=1 2 5 1, in format 2 and r=5 , k=1 1 3 , in format 1 and pos=3 2 5 1, in format 2 and r=5 , k=1 2 5 2, in format 2 and r=5 , k=2
the instructions of the second test case are : 2 7 2, in format 2 and r=7 , k=2 1 5 , in format 1 and pos=5 2 7 2, in format 2 and r=7 , k=2 2 8 9, in format 2 and r=8 , k=9 1 8 , in format 1 and pos=8 2 8 9, in format 2 and r=8 , k=9 the instructions of the third test case are : 1 10 , in format 1 and pos=10 2 8 9 , in format 2 and r=8 , k=9 1 7 , in format 1 and pos=7 2 4 4 , in format 2 and r=4 , k=4 1 8 , in format 1 and pos=8 2 5 7 , in format 2 and r=5 , k=7 1 1 , in format 1 and pos=1 1 4 , in format 1 and pos=4 2 10 10, in format 2 and r=10 , k=10 1 2 , in format 1 and pos=2 [/hint]

#include <bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
typedef int ll;
const int maxn=1e5+7;
const ll inf=1e9;
int n,m,str2[maxn];//str2是保存原本的值
struct inti{
    int data,poi;
}str[maxn];//保存原本的值之后排序,方便建立线段树
struct node{
    int l,r;
    int Maxr;
}arr[4*maxn];//线段树结构体数组
bool cmp(inti a,inti b){
    return a.data<b.data;
}
void build(int p,int l,int r){//建树
    arr[p].l=l,arr[p].r=r;
    if(l==r){
        arr[p].Maxr=str[l].poi;
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    arr[p].Maxr=max(arr[p*2].Maxr,arr[p*2+1].Maxr);//从下到上更新
}
void change(int p,int x){//把值为x的下标更新为n+1
    if(arr[p].l==arr[p].r){
        arr[p].Maxr=n+1;
        return;
    }
    int mid=(arr[p].l+arr[p].r)/2;
    if(x<=mid)change(p*2,x);
    else change(p*2+1,x);
    arr[p].Maxr=max(arr[p*2].Maxr,arr[p*2+1].Maxr);//从下到上更新最大区间下标
}
int ask(int p,int l,int r,int R){//询问l-r权值区间最小的且下标比R大的值,其实在这里r好像没用到,因为都是n+1
    if(arr[p].Maxr<=R)return n+1;
    if(arr[p].l==arr[p].r&&arr[p].l>=l){
        if(arr[p].Maxr>R)return arr[p].l;
        return n+1;
    }
    int mid=(arr[p].l+arr[p].r)/2;
    int val=n+1;//最大值为n+1
    if(l<=mid)val=min(val,ask(p*2,l,r,R));//取最小值
    if(r>mid)val=min(val,ask(p*2+1,l,r,R));//取最小值
    return val;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&n,&m);
        str[n+1].data=n+1,str[n+1].poi=n+1;
        for(int i=1;i<=n;++i)
            scanf("%d",&str[i].data),str[i].poi=i,str2[i]=str[i].data;
        sort(str+1,str+n+1,cmp);
        build(1,1,n+1);
        int id,a,b,lastans=0;
        while(m--){
            scanf("%d",&id);
            if(id==1){
                scanf("%d",&a);
                change(1,str2[a^lastans]);
            }
            else{
                scanf("%d %d",&a,&b);
                int r=a^lastans,k=b^lastans;
                int ans=ask(1,k,n+1,r);
                printf("%d\n",ans);
                lastans=ans;//更新lastans
            }
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/lengsong/p/11404522.html

时间: 2024-10-16 07:35:25

权值线段树模板题的相关文章

权值线段树板子题

https://www.luogu.org/problem/P1168 #include <bits/stdc++.h> using namespace std; const int maxn=1e5+5; int tree[maxn*4]; int dtc[maxn]; int a[maxn]; void pushup(int root) { tree[root]=tree[root<<1]+tree[root<<1|1]; } void update(int roo

wangdy带佬给的权值线段树模板

实为1027练习题C-遥色点对题解 给出一张由编号1到n的n个点和m条边构成的无向图.每条边都有一定的长度. 定义,一条路径的"代价":该路径上最长一条边的长度. 定义,点x到点y的"点距":点x到点y的最小代价. 图中每个点都被涂上了颜色,第i号点的颜色编号为Ci. 满足x<y 且|Cx-Cy|>=K 的任意一对点(x,y)都被称为"遥色点对" 现在需要你求出图中所有遥色点对的点距之和. 动态开点线段树启发式合并 #include&

详解权值线段树

详解权值线段树 本篇随笔详细讲解一下算法竞赛中的一种数据结构--权值线段树. 前置知识 在讲解权值线段树之前,我们首先要明确:权值线段树属于一种线段树,它的本质仍然是线段树.所以在学习权值线段树之前,如果还对普通线段树并没有一个深刻的了解的话,请先移步这篇博客来学习简单线段树. 简单线段树知识点详解 以及,权值线段树的本质是线段树维护桶.这个桶到底是什么呢?如果读者对桶的概念和应用比较模糊的话,请移步这篇博客来学习桶的基本概念和应用: 桶的基本概念和应用 权值线段树的概念 那么,在了解了所有的前

模板——权值线段树(逆序对)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 62455   Accepted: 23259 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin

[bzoj3932][CQOI2015]任务查询系统-题解[主席树][权值线段树]

Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行 ),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向 查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个 )的优先级之和是多少.特别的,如

【BZOJ4605】崂山白花蛇草水 权值线段树+kd-tree

[BZOJ4605]崂山白花蛇草水 Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了山东省省队,现在便是他履行诺言的时候了.蒟蒻Bob特地为他准备了999,999,999,999,999,999瓶崂山白花蛇草水,想要灌神犇Aleph.神犇Aleph求(跪着的)蒟蒻Bob不要灌他,由于神犇Aleph是神犇,蒟蒻Bob最终答应了他的请求,但蒟蒻Bob决定将计就计,也让神犇Aleph回答

【bzoj4605】崂山白花蛇草水 权值线段树套KD-tree

题目描述 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实力,他轻松地进了山东省省队,现在便是他履行诺言的时候了.蒟蒻Bob特地为他准备了999,999,999,999,999,999瓶崂山白花蛇草水,想要灌神犇Aleph.神犇Aleph求(跪着的)蒟蒻Bob不要灌他,由于神犇Aleph是神犇,蒟蒻Bob最终答应了他的请求,但蒟蒻Bob决定将计就计,也让神犇Aleph回答一些问题.具体说来,蒟蒻Bob会在一个宽敞的广场上

BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

题目大意:有一些位置,这些位置上可以放若干个数字.现在有两种操作. 1.在区间l到r上添加一个数字x 2.求出l到r上的第k大的数字是什么 思路:这种题一看就是树套树,关键是怎么套,怎么写.(话说我也不会来着..)最容易想到的方法就是区间线段树套一个权值线段树,但是区间线段树上的标记就会变得异常复杂.所以我们就反过来套,用权值线段树套区间线段树.这样修改操作在外线段树上就变成了单点修改,外线段树就不用维护标记了.在里面的区间线段树上维护标记就容易多了.具体实现见代码. CODE: #includ

B20J_2733_[HNOI2012]永无乡_权值线段树合并

Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛.现在有两种操作:B x y表示在岛 x与岛y之间修建一座新桥.Q x k表示询问当前与岛 x连通的所有岛中第k重要的是哪座岛,即所有与岛 x连通的岛中重要度排名第 k小的岛是哪座,请你输出那个岛的编号. 对于100%的数据n≤100000,m≤n,q≤300000. 分析:读懂题后发现是一道线段树合并的裸题.