社区讨论
线段树,但是50ptsMLE+TLE
P5019[NOIP 2018 提高组] 铺设道路参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lo87j58c
- 此快照首次捕获于
- 2023/10/27 14:03 2 年前
- 此快照最后确认于
- 2023/10/27 14:03 2 年前
CPP
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+5;
struct Info{
int pos,val;
};
int n,sum=0;
int a[N];
namespace SegmentTree{
int Min[N<<2],pos[N<<2],b[N<<2];
inline void pushup(int node){
if (Min[node<<1]>Min[node<<1 | 1]) {Min[node]=Min[node<<1 | 1],pos[node]=pos[node<<1 | 1];}
else {Min[node]=Min[node<<1],pos[node]=pos[node<<1];}
}
inline void pushdown(int node,int l,int r)
{
int mid=(l+r) >> 1;
if (b[node])
{
Min[node<<1]-=b[node];b[node<<1]+=b[node];
Min[node<<1 | 1]-=b[node];b[node<<1 | 1]+=b[node];
b[node]=0;
}
return ;
}
inline void build(int node,int l,int r)
{
if (l==r)
{
b[node]=0;
Min[node]=a[l];
pos[node]=l;
return ;
}
int mid=(l+r) >> 1;
build(node<<1,l,mid);
build(node<<1 | 1,mid+1,r);
pushup(node);
}
inline void minus(int node,int l,int r,int s,int t,int c)
{
// cout<<"minus! l:"<<s<<" r:"<<r<<" node:"<<node<<" l:"<<l<<" r:"<<r<<endl;
if (l<=s && r>=t)
{
Min[node]-=c;b[node]+=c;
return ;
}
int mid=(s+t) >> 1;
pushdown(node,s,t);
if (l<=mid) minus(node<<1,l,r,s,mid,c);
if (r>mid) minus(node<<1 | 1,l,r,mid+1,t,c);
pushup(node);
}
Info query(int node,int l,int r,int s,int t)
{
// cout<<"query! l:"<<s<<" r:"<<t<<" node:"<<node<<" val:"<<Min[node]<<" pos:"<<pos[node]<<endl;
if (l<=s && r>=t) return (Info){pos[node],Min[node]};
int mid=(s+t) >> 1;
pushdown(node,s,t);
Info Min_ans;Min_ans.val=0x3f;
if (l<=mid)
{
Info res=query(node<<1,l,r,s,mid);
if (Min_ans.val>res.val)
{Min_ans=res;}
}
if (r>mid)
{
Info res=query(node<<1 | 1,l,r,mid+1,t);
if (Min_ans.val>res.val)
{Min_ans=res;}
}
pushup(node);
return Min_ans;
}
void find(int l,int r)
{
// cout<<"find! l:"<<l<<" r:"<<r<<" sum:"<<sum<<endl;
if (l==r) {sum+=query(1,l,r,1,n).val;return ;}
Info nMin=query(1,l,r,1,n);
sum+=nMin.val;
minus(1,l,r,1,n,nMin.val);
int place=nMin.pos;
// cout<<"place!"<<place<<" val:"<<nMin.val<<endl;
if (place>l) find(l,place-1);
if (place<r) find(place+1,r);
}
}
using namespace SegmentTree;
inline int read(){
int s=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') {f=-1;} ch=getchar();}
while(isdigit(ch)) {s=(s<<1)+(s<<3)+ch-'0'; ch=getchar();}
return s*f;
}
inline void write(int x){
int top=0,sta[35];
while(x) {sta[top++]=x%10,x/=10;}
while(top) {putchar(sta[--top]+'0');}
}
int main()
{
n=read();
for (int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
find(1,n);
printf("%d",sum);
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...