求助上午比赛T1
  • 板块学术版
  • 楼主Access57
  • 当前回复5
  • 已保存回复5
  • 发布时间2022/11/20 15:51
  • 上次更新2023/10/27 02:12:46
查看原帖
求助上午比赛T1
267428
Access57楼主2022/11/20 15:51

rt,比赛时口胡了一个做法:离线操作,对于最终序列,倒着读取数据,对于2操作就取区间最小值。

只需线段树的区间加和区间最小值

所以这样是正确的吗,求正确性证明||hack

AC代码:

#include <bits/stdc++.h>
#define int long long
#define root 1,1,n
#define nows now,nowl,nowr
#define lson now<<1,nowl,m
#define rson now<<1|1,m+1,nowr
//#define mid (nowl+nowr)<<1
using namespace std;
const int Maxn=300010;
struct SegMent_Tree
{
    int val;
    int b;
    int mn;
    bool nop;
    int push_val;
    SegMent_Tree()
    {
        mn=1e18;//must be <=1e18
        push_val=val=b=nop=0;//don't use nop as nop&push_val because push_val might be 0
    }
}z[4*Maxn];//4x space

void clear(SegMent_Tree &node)
{
	node.mn=1e18;//must be <=1e18
    node.push_val=node.val=node.b=node.nop=0;//don't use nop as nop&push_val because push_val might be 0
}

int a[Maxn];

inline int ls(int node) {return node<<1;}
inline int rs(int node) {return node<<1|1;}

inline SegMent_Tree operator+(const SegMent_Tree &l,const SegMent_Tree &r)
{
    SegMent_Tree temp;
    temp.val=(l.val+r.val);
    temp.mn=min(l.mn,r.mn);
    return temp;
}

void build(int now,int nowl,int nowr)
{
    if(nowl==nowr) 
    {
        z[now].mn=z[now].val=a[nowl];//pay attention to now&nowl
        return;
    }

    int m=(nowl+nowr)>>1;

    build(lson),build(rson);

    z[now]=z[ls(now)]+z[rs(now)];
}

void color(int now,int nowl,int nowr,int plus)
{
    z[now].val=z[now].val+(nowr-nowl+1)*plus;
    z[now].b=z[now].b+plus;
    z[now].mn=z[now].mn+plus;
}

void modify(int now,int nowl,int nowr,int v)
{
    z[now].val=(nowr-nowl+1)*v;
    z[now].b=0;//remember to clear the plus_lazytag
    z[now].mn=v;
    z[now].nop=1;
    z[now].push_val=v;
}

void push_down(int now,int nowl,int nowr)
{
    int m=(nowl+nowr)>>1;

    if(z[now].nop)//preference
    {
        modify(lson,z[now].push_val);
        modify(rson,z[now].push_val);
        z[now].nop=0;
        z[now].push_val=0;
    }

    if(z[now].b)
    {
        color(lson,z[now].b);
        color(rson,z[now].b);
        z[now].b=0;
    }
}

void modify(int l,int r,int now,int nowl,int nowr,int v)
{
    if(l<=nowl&&nowr<=r) 
    {
        modify(nows,v);
        return;
    }

    int m=(nowl+nowr)>>1;
    push_down(nows);
    if(l<=m) modify(l,r,lson,v);//midcut!!!!!!!!!
    if(r>m) modify(l,r,rson,v);

    z[now]=z[ls(now)]+z[rs(now)];
}

void update_plus(int l,int r,int now,int nowl,int nowr,int plus)
{

    if(l<=nowl&&nowr<=r) 
    {
        color(nows,plus);
        return;
    }
    int m=(nowl+nowr)>>1;
    push_down(nows);
    if(l<=m) update_plus(l,r,lson,plus);
    if(r>m) update_plus(l,r,rson,plus);

    z[now]=z[ls(now)]+z[rs(now)];
}

SegMent_Tree query(int l,int r,int now,int nowl,int nowr)
{

    if(l<=nowl&&nowr<=r) 
    {
        return z[now];
    }

    int m=(nowl+nowr)>>1;   
    push_down(nows);

    SegMent_Tree temp;
    if(l<=m) temp=temp+query(l,r,lson);
    if(r>m) temp=temp+query(l,r,rson);

    return temp;
}
vector<int> r_ans;
int T,n,m,b,c,d,opt;
int op[Maxn],lpos[Maxn],rpos[Maxn],L[Maxn];
signed main()
{
    ios::sync_with_stdio(0);
    cin>>T;
    while(T--)
    {
    	r_ans.clear();
    	for(int i=0;i<=300000;i++) clear(z[i]);
    	memset(op,0,sizeof(op)),memset(lpos,0,sizeof(lpos)),memset(rpos,0,sizeof(rpos)),memset(L,0,sizeof(L));
    	
    	cin>>n>>m;
	    for(int i=1;i<=n;i++) cin>>a[i];
	    for(int i=0;i<m;i++) 
	    {
	    	cin>>op[i]>>lpos[i]>>rpos[i];
	    	if(op[i] == 1) cin>>L[i];
		}
		for(int i=1;i<=n;i++) cin>>a[i];
		
		
	    build(root);//build build build build build!!!
	    for(int i=m-1;i>=0;i--)    
	    {
	    	opt = op[i]; b = lpos[i] , c = rpos[i];
	        if(opt==1)
	        {
	            d = L[i];
	            update_plus(b,c,root,-d);
	        }
	        else
	        {
	            r_ans.push_back(query(b,c,root).mn);
	        }
	    }
	    for(int i=r_ans.size()-1;i>=0;i--) cout<<r_ans[i]<<" ";
	    cout<<"\n";
	}
}
2022/11/20 15:51
加载中...