zoukankan      html  css  js  c++  java
  • 联考20200525 T1 数据结构



    分析:
    这道题可以看做单点修改区间查询历史最小值的数据结构题
    区间修改单点查询历史版本可以使用二维数据结构维护
    由于卡空间,这里只能选择KD树
    在KD树上区间修改,历史最值只需要统计单点到根节点的路径上记录的历史最值就行了
    关键是这道题如何转化?
    我们把询问离线,每一个查询((l,r))看做坐标轴上的单点
    单点(x)的修改可以看做对横坐标为([1,x])纵坐标([x,n])的矩形区间修改
    于是转化成了区间修改单点查询
    KD树上每个节点存储当前状态和懒标记状态(状态包含当前值和历史最值)

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    
    #define maxn 200005
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    inline int getint()
    {
    	int num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n,m,N,rt;
    int a[maxn],op[maxn],x[maxn],y[maxn],id[maxn];
    long long sum[maxn];
    struct data{
    	long long num,mn;
    	data(){}data(long long x){num=mn=x;}
    	inline void update(data p){mn=min(mn,num+p.mn),num+=p.num;}
    };
    struct node{
    	int d[2],mn[2],mx[2],ch[2],fa;
    	data val,lz;
    }t[maxn];
    inline bool cmp0(int x,int y){return t[x].d[0]<t[y].d[0];}
    inline bool cmp1(int x,int y){return t[x].d[1]<t[y].d[1];}
    inline void update(node &p)
    {
    	p.mn[0]=p.mx[0]=p.d[0],p.mn[1]=p.mx[1]=p.d[1];
    	for(int i=0;i<2;i++)if(p.ch[i])for(int j=0;j<2;j++)
    		p.mn[j]=min(p.mn[j],t[p.ch[i]].mn[j]),p.mx[j]=max(p.mx[j],t[p.ch[i]].mx[j]);
    }
    inline void pushdown(int i)
    {
    	if(t[i].lz.mn||t[i].lz.num)
    	{
    		if(t[i].ch[0])t[t[i].ch[0]].val.update(t[i].lz),t[t[i].ch[0]].lz.update(t[i].lz);
    		if(t[i].ch[1])t[t[i].ch[1]].val.update(t[i].lz),t[t[i].ch[1]].lz.update(t[i].lz);
    		t[i].lz=data(0);
    	}
    }
    
    inline void build(int &now,int l,int r,int D)
    {
    	int mid=(l+r)>>1;
    	nth_element(id+l,id+mid,id+r+1,D?cmp1:cmp0);now=id[mid];
    	if(l<mid)build(t[now].ch[0],l,mid-1,D^1);
    	if(mid<r)build(t[now].ch[1],mid+1,r,D^1);
    	t[t[now].ch[0]].fa=t[t[now].ch[1]].fa=now;
    	update(t[now]);
    }
    inline void update(int i,int num,int p)
    {
    	if(!i||p<t[i].mn[0]||p>t[i].mx[1])return;
    	if(p>=t[i].mx[0]&&p<=t[i].mn[1]){t[i].val.update(data(num)),t[i].lz.update(data(num));return;}
    	pushdown(i);
    	if(p>=t[i].d[0]&&p<=t[i].d[1])t[i].val.update(data(num));
    	update(t[i].ch[0],num,p),update(t[i].ch[1],num,p);
    }
    inline void pdpath(int x){if(t[x].fa)pdpath(t[x].fa);pushdown(x);}
    
    int main()
    {
    	n=getint(),m=getint();
    	for(int i=1;i<=n;i++)sum[i]=sum[i-1]+(a[i]=getint());
    	for(int i=1;i<=m;i++)
    	{
    		op[i]=getint(),x[i]=getint(),y[i]=getint();
    		if(op[i]==2)t[++N].d[0]=x[i],t[N].d[1]=y[i],t[N].val=data(sum[y[i]]-sum[x[i]-1]),id[N]=N;
    	}
    	build(rt,1,N,0);
    	for(int i=1,k=0;i<=m;i++)
    	{
    		if(op[i]&1)update(rt,y[i]-a[x[i]],x[i]),a[x[i]]=y[i];
    		else pdpath(++k),printf("%lld
    ",t[k].val.mn);
    	}
    }
    

  • 相关阅读:
    高效沟通
    Oracle播放多条 INSERT ALL
    oracle的同义词总结
    Brute force Attack
    爱因斯坦方程与小黑洞
    dom 编程(html和xml)
    dexposed框架Android在线热修复
    从微软小冰看微软运营手段的转型
    剑指offer_面试题_从上往下打印二叉树
    外面的wifi非常精彩,外面的wifi非常不安
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12961052.html
Copyright © 2011-2022 走看看