广告:
#include <stdio.h>
int main()
{
puts("转载请注明出处[vmurder]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/44037685");
}
题解:
先排序然后插入线段树
用线段树每次对全区间进行操作。
然后维护哪些段区间溢出了,对这段区间进行赋值。
溢出处理:
一个区间的左端点大于最大值,或者右端点小于最小值
那么这个区间就该被覆盖。
覆盖,加特技:
乘0+x就是覆盖成x。
剪枝?:
一个区间右端点≤最大值,或者左端点≥最小值,那么return
数据一组:
3 3 3044
- 9999
@ 3
- 1367
2
850
127
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 101000
#define ls (note<<1)
#define rs (note<<1|1)
using namespace std;
struct LSH
{
long long x;
int p;
bool operator < (const LSH &a)const
{return x<a.x;}
void read(int n){scanf("%lld",&x),p=n;}
}lsh[N];
struct OPT
{
int f;
long long a;
void read(int p){scanf("%lld",&a),f=p;}
}opt[N];
int n,m;
long long L,R,ans[N];
struct KSD
{
int l,r,s;
long long A,B,C;
long long L,R,lx,rx;
}s[N<<2];
inline void pushdown(int note) // 乘法C不影响其它
{
if(s[note].C!=1)
{
s[note].L*=s[note].C;
s[note].R*=s[note].C;
if(s[note].l<s[note].r)
{
s[ls].A*=s[note].C;
s[ls].B*=s[note].C;
s[ls].C*=s[note].C;
s[rs].A*=s[note].C;
s[rs].B*=s[note].C;
s[rs].C*=s[note].C;
}
s[note].C=1;
}
if(s[note].A)
{
s[note].L+=s[note].A;
s[note].R+=s[note].A;
if(s[note].l<s[note].r)
{
s[ls].A+=s[note].A;
s[rs].A+=s[note].A;
}
s[note].A=0;
}
if(s[note].B)
{
s[note].L+=s[note].B*s[note].lx;
s[note].R+=s[note].B*s[note].rx;
if(s[note].l<s[note].r)
{
s[ls].B+=s[note].B;
s[rs].B+=s[note].B;
}
s[note].B=0;
}
return ;
}
inline void pushup(int note)
{
s[note].L=s[ls].L;
s[note].R=s[rs].R;
return ;
}
void build(int note,int l,int r)
{
s[note].l=l,s[note].r=r;
s[note].C=1;
if(l==r)
{
s[note].L=s[note].R=s[note].lx=s[note].rx=lsh[l].x;
s[note].s=lsh[l].p;
return ;
}
int mid=l+r>>1;
build(ls,l,mid),build(rs,mid+1,r);
s[note].lx=s[ls].lx,s[note].rx=s[rs].rx;
pushup(note);
return ;
}
void add(int note,long long w,int f)
{
if(f==0)s[note].A+=w;
else s[note].B+=w;
pushdown(note);
}
void mul(int note,long long w)
{
s[note].A*=w,s[note].B*=w,s[note].C*=w;
pushdown(note);
}
// void cover(x) -> mul(0),add(x,0)
void keep(int note)
{
pushdown(note);
if(s[note].L>R)
{
s[note].A=R;
s[note].B=0;
s[note].C=0;
pushdown(note);
return ;
}
if(s[note].R<L)
{
s[note].A=L;
s[note].B=0;
s[note].C=0;
pushdown(note);
return ;
}
if(s[note].R<=R&&s[note].L>=L)return ;
int mid=s[note].l+s[note].r>>1;
keep(ls),keep(rs),pushup(note);
}
void dfs(int note)
{
pushdown(note);
if(s[note].l==s[note].r)
{
ans[s[note].s]=s[note].L;
return ;
}
dfs(ls),dfs(rs);
}
char ss[5];
int main()
{
freopen("test.in","r",stdin);
int i;
scanf("%d%lld%lld",&m,&L,&R);
for(i=1;i<=m;i++)
{
scanf("%s",ss);
if(ss[0]==‘+‘)opt[i].read(1);
else if(ss[0]==‘-‘)opt[i].read(2);
else if(ss[0]==‘*‘)opt[i].read(3);
else if(ss[0]==‘@‘)opt[i].read(4);
}
scanf("%d",&n);
for(i=1;i<=n;i++)lsh[i].read(i);
sort(lsh+1,lsh+n+1);
build(1,1,n);
for(i=1;i<=m;i++)
{
if(opt[i].f==1)add(1,opt[i].a,0);
else if(opt[i].f==2)add(1,-opt[i].a,0);
else if(opt[i].f==3)mul(1,opt[i].a);
else if(opt[i].f==4)add(1,opt[i].a,1);
keep(1);
}
dfs(1);
for(i=1;i<=n;i++)printf("%lld\n",ans[i]);
return 0;
}
时间: 2024-10-15 21:45:11