• ●线段树题之wows


    ●模拟考试的一道似乎是学长出的题,还不错,挺考代码能力的。以此记录。

    ●题目以被上传(改了改说法),6128 Lence的方块们

    题目

    (像手纸一样长的贴图……)

    ●题目大意:

       有横向排布的n个点,每个点初始值都为0。

       有m个操作(先输入操作类型com):

         com==0:修改操作(接着输入l , r , a , k , p),解释见输入格式。(提供图帮助理解)。

        操作0

         com==1:查询操作(接着输入l , r),输出区间[ l , r ]内最长的等差数列的项数(要连续)。

    ●题解:

         注意到是要找等差数列,即答案对应的区间个元素的差值应相等。即可以前后两元素的差值建线段树,然后维护区间最长的差值相等的一段。

         (是不是思路很清晰,然而恶心的代码却搞了我大半个上午。)

    ●附上代码:

    我上代码咯:(附上测试数据)
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    struct segment{
    	int l,r,nl,nr,mx,ml,mr,lazy;
    }t[400005]; 
    int n,m;
    void pushdown(int u)
    {
    	t[u*2].lazy+=t[u].lazy; t[u*2].nl+=t[u].lazy; t[u*2].nr+=t[u].lazy;
    	t[u*2+1].lazy+=t[u].lazy; t[u*2+1].nl+=t[u].lazy; t[u*2+1].nr+=t[u].lazy;
    	t[u].lazy=0;
    }
    void pushup(int u)
    {
    	t[u].mx=max(t[u*2].mx,t[u*2+1].mx);
    	t[u].ml=t[u*2].ml;
    	t[u].mr=t[u*2+1].mr;
    	t[u].nl=t[u*2].nl;                  
    	t[u].nr=t[u*2+1].nr;                
    	if(t[u*2].nr==t[u*2+1].nl)
    	{
    		t[u].mx=max(t[u].mx,t[u*2].mr+t[u*2+1].ml);
    		if(t[u*2].ml==(t[u*2].r-t[u*2].l+1)) t[u].ml+=t[u*2+1].ml;
    		if(t[u*2+1].mr==(t[u*2+1].r-t[u*2+1].l+1)) t[u].mr+=t[u*2].mr;
    	}
    }
    void build(int u,int l,int r)
    {
    	t[u]=(segment){l,r,0,0,r-l+1,r-l+1,r-l+1};
    	if(l==r) return;
    	int mid=(l+r)/2;
    	build(u*2,l,mid);
    	build(u*2+1,mid+1,r);
    }
    void add(int u,int l,int r,int x)
    {
    	if(l<=t[u].l&&t[u].r<=r)
    	{
    		t[u].nl+=x;
    		t[u].nr+=x;
    		t[u].lazy+=x;
    		return;
    	}
    	if(t[u].lazy) pushdown(u);
    	int mid=(t[u].l+t[u].r)/2;
    	if(l<=mid) add(u*2,l,r,x);
    	if(mid<r) add(u*2+1,l,r,x);
    	pushup(u); 
    }
    void query(int u,int l,int r,int &mx,int &lm,int &rm,int &ln,int &rn)
    {
    	int lmx=0,lml,lmr,lnl,lnr,rmx=0,rml,rmr,rnl,rnr;
    	if(t[u].l==l&&t[u].r==r)
    	{
    		mx=t[u].mx; lm=t[u].ml; rm=t[u].mr; ln=t[u].nl; rn=t[u].nr;
    		return;
    	}
    	if(t[u].lazy) pushdown(u);
    	int mid=(t[u].l+t[u].r)/2;
    	if(l<=mid) query(u*2,l,min(mid,r),lmx,lml,lmr,lnl,lnr);
    	if(mid<r) query(u*2+1,max(mid+1,l),r,rmx,rml,rmr,rnl,rnr);
    	if(lmx*rmx!=0)
    	{
    		mx=max(lmx,rmx);
    		ln=lnl; rn=rnr; lm=lml; rm=rmr;
    		if(lnr==rnl) 
    		{
    			mx=max(mx,lmr+rml);
    			if(lml==mid-l+1) lm+=rml;
    			if(rmr==r-(mid+1)+1) rm+=lmr;
    		}
    	}
    	else
    	{
    		if(lmx==0) swap(lmx,rmx),swap(lml,rml),swap(lmr,rmr),swap(lnl,rnl),swap(lnr,rnr);
    		mx=lmx; lm=lml; rm=lmr; ln=lnl; rn=lnr;
    	}
    }
    int main()
    {
    	freopen("wows.in","r",stdin);
    	freopen("wows.out","w",stdout);
    	scanf("%d%d",&n,&m);n--;
    	build(1,1,n); int com;
    	for(int i=1,l,r,a,k,p;i<=m;i++)
    	{
    		scanf("%d",&com);
    		if(com==0) 
    		{
    			scanf("%d%d%d%d%d",&l,&r,&a,&k,&p);
    			if(l>1) add(1,l-1,l-1,a);
    			if(p-1>=l) add(1,l,p-1,k);
    			if(r-1>=p) add(1,p,r-1,-k);
    			if(r<n) add(1,r,r,-(a+(2*p-l-r)*k));
    		}
    		if(com==1)
    		{
    			int ans,a1,a2,a3,a4;
    			scanf("%d%d",&l,&r); r--;
    			query(1,l,r,ans,a1,a2,a3,a4);
    			printf("%d
    ",ans+1);
    		}
    	}
    	return 0;
    }
    


    Do not go gentle into that good night.
    Rage, rage against the dying of the light.
    ————Dylan Thomas
  • 相关阅读:
    idea新建web项目
    wampserver的MySQL和本机MySQL冲突导致空密码登录报错
    while-else if
    格式化输出
    Zookeeper
    仿真手写Spring核心原理v1.0
    各设计模式总结与对比
    装饰者模式和观察者模式
    模板模式和适配器模式
    委派模式和策略模式
  • 原文地址:https://www.cnblogs.com/zj75211/p/6881749.html
Copyright © 2020-2023  润新知