• 联考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);
    	}
    }
    

  • 相关阅读:
    UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
    Codeforces 482E ELCA (LCT)
    Codeforces 798D Mike and distribution (构造)
    AtCoder AGC017C Snuke and Spells
    HDU 6089 Rikka with Terrorist (线段树)
    HDU 6136 Death Podracing (堆)
    AtCoder AGC032D Rotation Sort (DP)
    jenkins+python+kubectl实现批量更新k8s镜像
    Linux 下载最新kubectl版本的命令:
    jenkins X 和k8s CI/CD
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12961052.html
Copyright © 2020-2023  润新知