数据结构 解题报告

数据结构

给一个长为\(n\)\(A\),定义\(n\times n\)\(B_{l,r}=\sum\limits_{i=l}^rA_i\),两个操作,修改\(A_p\)\(x\),询问\(B_{l,r}\)的历史最小值。


我居然把D1T1鸽到D4晚上...

历史最值+kd-tree

先离线的把点放到kd-tree中(要离散化)

然后就是矩形加和单点查询,打一下历史最值的标记就好了

我主要还是熟悉一下kd-tree,第三次打这玩意儿

注意kd-tree查询点应该怎么写


Code:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define ll long long
const int N=1e5+5;
using std::min;
using std::max;
template <class T>
void read(T &x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
int ch[N][2],L[N][2],R[N][2],pos[N][2],num[N],tot,root;
ll mi[N],dat[N],tag[N],histag[N],f[N];
#define ls ch[now][0]
#define rs ch[now][1]
void updata(int now)
{
	L[now][0]=R[now][0]=pos[now][0];
	L[now][1]=R[now][1]=pos[now][1];
	if(ls)
	{
		L[now][0]=min(L[now][0],L[ls][0]);
		L[now][1]=min(L[now][1],L[ls][1]);
		R[now][0]=max(R[now][0],R[ls][0]);
		R[now][1]=max(R[now][1],R[ls][1]);
	}
	if(rs)
	{
		L[now][0]=min(L[now][0],L[rs][0]);
		L[now][1]=min(L[now][1],L[rs][1]);
		R[now][0]=max(R[now][0],R[rs][0]);
		R[now][1]=max(R[now][1],R[rs][1]);
	}
}
void pushdown(int now)
{
	if(tag[now])
	{
		if(ls)
		{
			mi[ls]=min(mi[ls],dat[ls]+histag[now]);
			dat[ls]+=tag[now];
			histag[ls]=min(histag[ls],tag[ls]+histag[now]);
			tag[ls]+=tag[now];
		}
		if(rs)
		{
			mi[rs]=min(mi[rs],dat[rs]+histag[now]);
			dat[rs]+=tag[now];
			histag[rs]=min(histag[rs],tag[rs]+histag[now]);
			tag[rs]+=tag[now];
		}
		tag[now]=histag[now]=0;
	}
}
int nk;
bool cmp(int a,int b)
{
    return pos[a][nk]==pos[b][nk]?pos[a][nk^1]<pos[b][nk^1]:pos[a][nk]<pos[b][nk];
}
void build(int &now,int l,int r,int k)
{
	if(l>r){now=0;return;}
	int mid=l+r>>1;nk=k;
	std::nth_element(num+l,num+mid,num+r+1,cmp);
	now=num[mid];
	build(ls,l,mid-1,k^1),build(rs,mid+1,r,k^1);
	updata(now);
}
bool ckm(int a,int b,int c,int d){return b<c||a>d;}
bool ck(int a,int b,int c,int d){return a<=c&&d<=b;}
void modi(int now,int a,int b,int c,int d,int delta)
{
	 if(!now) return;
	 if(ckm(L[now][0],R[now][0],a,c)||ckm(L[now][1],R[now][1],b,d)) return;
	 if(ck(a,c,L[now][0],R[now][0])&&ck(b,d,L[now][1],R[now][1]))
	 {
	 	mi[now]=min(mi[now],dat[now]+delta);
	 	dat[now]+=delta;
	 	histag[now]=min(histag[now],tag[now]+delta);
	 	tag[now]+=delta;
	 	return;
	 }
	 pushdown(now);
	 if(a<=pos[now][0]&&pos[now][0]<=c&&b<=pos[now][1]&&pos[now][1]<=d)
	 {
	 	dat[now]=dat[now]+delta;
	 	mi[now]=min(mi[now],dat[now]);
	 }
	 modi(ls,a,b,c,d,delta),modi(rs,a,b,c,d,delta);
}
ll query(int now,int a,int b,int k)
{
	if(pos[now][0]==a&&pos[now][1]==b) return mi[now];
	pushdown(now);
	int mid=pos[now][k];
	if(k)
    {
        if(b<pos[now][k]||(b==pos[now][k]&&a<pos[now][k^1])) return query(ls,a,b,k^1);
        else return query(rs,a,b,k^1);
    }
    else
    {
        if(a<pos[now][k]||(a==pos[now][k]&&b<pos[now][k^1])) return query(ls,a,b,k^1);
        else return query(rs,a,b,k^1);
    }
}
struct koito_yuu
{
	int op,p,x;
}yuu[N];
struct yuyuyu
{
    int l,r;
    bool friend operator <(yuyuyu a,yuyuyu b)
    {
        return a.l==b.l?a.r<b.r:a.l<b.l;
    }
    bool friend operator ==(yuyuyu a,yuyuyu b)
    {
        return a.l==b.l&&a.r==b.r;
    }
}yuy[N];
int n,m,a[N];
int main()
{
    //freopen("ds.in","r",stdin);
    //freopen("ds.out","w",stdout);
	read(n),read(m);
	for(int i=1;i<=n;i++) read(a[i]),f[i]=f[i-1]+a[i];
	for(int i=1;i<=m;i++)
	{
		read(yuu[i].op);
		if(yuu[i].op==1)
        {
            read(yuu[i].p);
            read(yuu[i].x);
        }
		if(yuu[i].op==2)
		{
		    ++tot;
		    read(yuy[tot].l);
		    read(yuy[tot].r);
		    yuu[i].p=yuy[tot].l,yuu[i].x=yuy[tot].r;
		}
	}
	std::sort(yuy+1,yuy+1+tot);
	tot=std::unique(yuy+1,yuy+1+tot)-yuy-1;
	for(int i=1;i<=tot;i++)
    {
        num[i]=i;
        pos[i][0]=yuy[i].l;
        pos[i][1]=yuy[i].r;
        dat[i]=mi[i]=f[yuy[i].r]-f[yuy[i].l-1];
    }
	build(root,1,tot,0);
	for(int i=1;i<=m;i++)
	{
		if(yuu[i].op==1) modi(root,1,yuu[i].p,yuu[i].p,n,yuu[i].x-a[yuu[i].p]),a[yuu[i].p]=yuu[i].x;
		else printf("%lld\n",query(root,yuu[i].p,yuu[i].x,0));
	}
	return 0;
}

2019.3.24

posted @ 2019-03-24 21:00  露迭月  阅读(205)  评论(0编辑  收藏  举报