IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> P6617 查找 Search 线段树 查找区间内是否有两个和为w的数(w不变) -> 正文阅读

[数据结构与算法]P6617 查找 Search 线段树 查找区间内是否有两个和为w的数(w不变)

题解:
每个点x,设置其前驱为离其最近的w-x的位置
每次修改可能影响O(n)个位置:
w-x x x x x x x…
这样后面每个位置的前驱都是w-x
如果修改了w-x的值,这样会导致O(n)个修改

注意到这个是存在性判定
如果存在两个 ( i 1 , j 1 ) , ( i 2 , j 2 ) (i_1,j_1),(i_2,j_2) (i1?,j1?)(i2?,j2?)使得 a [ i 1 ] + a [ j 1 ] = w , a [ i 2 ] + a [ j 2 ] = w a[i_1]+a[j_1]=w,a[i_2]+a[j_2]=w a[i1?]+a[j1?]=w,a[i2?]+a[j2?]=w,而且 [ i 2 , j 2 ] [i_2,j_2] [i2?,j2?]包含了 [ i 1 , j 1 ] [i_1,j_1] [i1?,j1?],则 ( i 2 , j 2 ) (i_2,j_2) (i2?,j2?)没有任何意义
这样每个点只存在 O ( 1 ) O(1) O(1)个配对关系

由于是存在性,所以我们维护b[i]表示每个点的前驱
如果区间 [ l , r ] [l,r] [l,r] b [ i ] b[i] b[i]最大值在 [ l , r ] [l,r] [l,r]中,则存在,否则不存在
这样只需要线段树求最大值,和multiset维护前驱后继即可

—来自李欣隆大师的讲解。

代码:

#include<bits/stdc++.h>
#define endl '\n'
//#define int long long

using namespace std;

const int maxn=5e5+10;

bool previsited[maxn],sufvisited[maxn];
multiset<int> ss[maxn];
int pre[maxn],suf[maxn];
int a[maxn];
int imax[maxn<<2];
void update(int node,int start,int ends,int pos,int val){
    if(start==ends){
        imax[node]=val;
        return ;
    }
    int mid=(start+ends)>>1;
    if(pos<=mid) update(node<<1,start,mid,pos,val);
    else update(node<<1|1,mid+1,ends,pos,val);
    imax[node]=max(imax[node<<1],imax[node<<1|1]);
}
int query(int node,int start,int ends,int l,int r){
    if(l<=start&&ends<=r){
        return imax[node];
    }
    int mid=(start+ends)>>1;
    int res=0;
    if(l<=mid) res=max(res,query(node<<1,start,mid,l,r));
    if(mid<r) res=max(res,query(node<<1|1,mid+1,ends,l,r));
    return res;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m,w;
    cin>>n>>m>>w;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(ss[w-a[i]].size()!=0){
            set<int>::iterator it=ss[w-a[i]].end();
            it--;
            if(!sufvisited[*it]){
                sufvisited[*it]=true;
                previsited[i]=true;
                pre[i]=*it;
                suf[*it]=i;
                update(1,1,n,i,pre[i]);
            }
        }
        ss[a[i]].insert(i);
    }
    int cnt=0;
    for(int i=1;i<=m;i++){
        int opt;
        cin>>opt;
        if(opt==1){
            int x,y;
            cin>>x>>y;
            if(a[x]==y) continue;
            ss[a[x]].erase(x);
            ss[y].insert(x);
            sufvisited[x]=false;
            previsited[x]=false;
            if(pre[x]!=0) sufvisited[pre[x]]=false;
            if(suf[x]!=0) previsited[suf[x]]=false;
            update(1,1,n,x,0);
            if(suf[x])  update(1,1,n,suf[x],0);

            if(pre[x]!=0){   //修改前驱结点
                set<int>::iterator it=ss[w-a[pre[x]]].upper_bound(pre[x]);
                suf[pre[x]]=0;
                if(it!=ss[w-a[pre[x]]].end()&&!previsited[*it]){
                    //cout<<"now  "<<x<<endl;
                    previsited[*it]=true;
                    sufvisited[pre[x]]=true;
                    suf[pre[x]]=*it;
                    pre[*it]=pre[x];
                    update(1,1,n,*it,pre[*it]);
                    //cout<<"debug  "<<endl;
                }
                else{

                }
            }
            if(suf[x]!=0){  //修改后驱节点
                set<int>::iterator it=ss[w-a[suf[x]]].lower_bound(suf[x]);
                pre[suf[x]]=0;
                if(it!=ss[w-a[suf[x]]].begin()){
                    it--;
                    if(*it<suf[x]&&!sufvisited[*it]){
                        sufvisited[*it]=true;
                        previsited[suf[x]]=true;
                        pre[suf[x]]=*it;
                        suf[*it]=suf[x];
                        update(1,1,n,suf[x],pre[suf[x]]);
                        //cout<<"debug  "<<endl;
                    }
                }
            }
            a[x]=y;
            pre[x]=suf[x]=0;

            set<int>::iterator it=ss[w-a[x]].lower_bound(x);  
            if(it!=ss[w-a[x]].begin()){  //求改结点本身(向前连)
                it--;
                //cout<<"debug  "<<*it<<endl;
                if(*it<x){
                    if(!sufvisited[*it]){
                        //cout<<"debug  "<<*it<<endl;
                        sufvisited[*it]=true;
                        previsited[x]=true;
                        pre[x]=*it;
                        suf[*it]=x;
                        update(1,1,n,x,pre[x]);
                        //cout<<"update "<<x<<" "<<pre[x]<<endl;
                    }
                    else {
                        if(suf[*it]>x){
                            pre[suf[*it]]=0;
                            previsited[suf[*it]]=false;

                            pre[x]=*it;
                            suf[*it]=x;
                            previsited[x]=true;
                            update(1,1,n,x,*it);
                        }
                    }
                }
            }
            it=ss[w-a[x]].upper_bound(x);  //修改结点本身(向后连)
            if(it!=ss[w-a[x]].end()){
                if(!previsited[*it]){
                    previsited[*it]=true;
                    sufvisited[x]=true;
                    pre[*it]=x;
                    suf[x]=*it;
                    update(1,1,n,suf[x],pre[suf[x]]);
                }
                else{
                    if(pre[*it]<x){
                        suf[pre[*it]]=0;
                        sufvisited[pre[*it]]=false;
                        pre[*it]=x;
                        sufvisited[x]=true;
                        suf[x]=*it;
                        update(1,1,n,*it,x);
                    }
                }
            }
        }
        else{
            int l,r;
            cin>>l>>r;
            l=l^cnt,r=r^cnt;
            int ans=query(1,1,n,l,r);
            //cout<<"debug   "<<l<<" "<<r<<" "<<ans<<endl;
            if(ans>=l){
                cnt++;
                cout<<"Yes"<<endl;
            }
            else cout<<"No"<<endl;
        }
    }


}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-29 09:37:13  更:2021-08-29 09:39:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/25 2:25:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码