• 数据结构 解题报告


    数据结构

    给一个长为(n)(A),定义(n imes n)(B_{l,r}=sumlimits_{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
    ",query(root,yuu[i].p,yuu[i].x,0));
    	}
    	return 0;
    }
    

    2019.3.24

  • 相关阅读:
    hdu 4123 树形dp+rmq
    POJ 2761 Feed the dogs 求区间第k大 划分树
    hdu 4585 shaolin 平衡树
    *hdu 4616 Game 树形DP
    hdu 5379 Mahjong tree 树形DP入门
    CF 581F Contest Page 树形DP
    hdu 2778 LCR 模拟题
    hdu 2896 病毒侵袭 AC自动机
    hdu 2222 Keywords Search AC自动机模板题
    透过c的编程原则,来规范自己现在的一些编程习惯
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10590334.html
Copyright © 2020-2023  润新知