【NOIP】借教室(線段樹)
阿新 • • 發佈:2019-02-12
題解明天寫(因為今天腦子好像沒了)
來了……PS:該題正解是貪心。
用線段樹做的原因是被坑了。
區間修改,記錄一個treemin,當treemin<0就輸出答案。
洛谷95分 codevs AC的程式碼:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define lson num<<1,l,mid
#define rson num<<1|1,mid+1,r
using namespace std;
int n,m;
int j;
bool flag=1;
const int maxn=1000000+5;
int tree[maxn<<2],treemin[maxn<<2],lazy[maxn<<2],a[maxn];
void push_up(int num)
{
tree[num]=tree[num<<1]+tree[num<<1|1];
treemin[num]=min(treemin[num<<1],treemin[num<<1|1]);
return;
}
void push_down(int num,int len)
{
tree[num<<1]+=lazy[num]*(len-(len>>1));
treemin[num<<1]+=lazy[num];
lazy[num<<1]+=lazy[num];
tree[num<<1|1]+=lazy[num]*(len>>1);
treemin[num<<1|1]+=lazy[num];
lazy[num<<1|1]+=lazy[num];
lazy[num]=0;
return ;
}
void build(int num,int l,int r)
{
if(l==r)
{
tree[num]=treemin[num]=a[l];
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
push_up(num);
return;
}
void update(int L,int R,int delta,int num,int l,int r)
{
if(flag)
{
if(L<=l&&r<=R)
{
lazy[num]+=delta;
tree[num]+=delta*(r-l+1);
treemin[num]+=delta;
if(treemin[num]<0)
{
cout<<-1<<'\n'<<j<<'\n';
flag=0;
}
return;
}
if (lazy[num]) push_down(num,r-l+1);
int mid=(l+r)>>1;
if(L<=mid) update(L,R,delta,lson);
if(R>mid) update(L,R,delta,rson);
push_up(num);
return;
}
}
void read(int &a)
{
a=0;
int h=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
h=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
a*=10;
a+=c-'0';
c=getchar();
}
a*=h;
}
int main()
{
read(n); read(m);
for(int i=1;i<=n;i++) read(a[i]);
build(1,1,n);
int b,c,d;
for(j=1;j<=m;j++)
{
read(b);read(c);read(d);
update(c,d,-b,1,1,n);
}
if(flag) cout<<0<<'\n';
return 0;
}