社区讨论
谁能帮我分析一下时间复杂度
P4344[SHOI2015] 脑洞治疗仪参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @m5te2on0
- 此快照首次捕获于
- 2025/01/12 17:04 去年
- 此快照最后确认于
- 2025/01/12 21:22 去年
A了,但时间复杂度不会分析。哪个好心人帮我分析一下,谢谢。
CPP#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
void write(int x)
{
if(x<0)putchar('-'),x=-x;
if(x<10)putchar(x+'0');
else write(x/10),putchar(x%10+'0');
}
const int N=2e6;
const int mod=1e9+7;
struct node{
int l,r,lmax,rmax,maxn,tag,sum,nsum;
node(){
lmax=rmax=maxn=sum=nsum=0;
tag=-1;
}
}tree[N];
void push_up(int p){
tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
tree[p].nsum=tree[p<<1|1].nsum+tree[p<<1].nsum;
tree[p].maxn=max(tree[p<<1].maxn,max(tree[p<<1|1].maxn,tree[p<<1].rmax+tree[p<<1|1].lmax));
tree[p].lmax=tree[p<<1].lmax+(tree[p<<1].lmax==tree[p<<1].r-tree[p<<1].l+1?tree[p<<1|1].lmax:0);
tree[p].rmax=tree[p<<1|1].rmax+(tree[p<<1|1].rmax==tree[p<<1|1].r-tree[p<<1|1].l+1?tree[p<<1].rmax:0);
return;
}
void build(int p,int l,int r){
tree[p].l=l;
tree[p].r=r;
if(l==r){
tree[p].nsum=1;
return;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
push_up(p);
return;
}
void pushdown(int p){
if(tree[p].tag<0)return;
if(tree[p].tag){
tree[p<<1].sum=tree[p<<1|1].sum=tree[p<<1].lmax=tree[p<<1].rmax=tree[p<<1|1].lmax=tree[p<<1|1].rmax=tree[p<<1].maxn=tree[p<<1|1].maxn=0;
tree[p<<1].nsum=tree[p<<1].r-tree[p<<1].l+1;
tree[p<<1|1].nsum=tree[p<<1|1].r-tree[p<<1|1].l+1;
tree[p<<1].tag=tree[p<<1|1].tag=1;
}
else{
tree[p<<1].maxn=tree[p<<1].lmax=tree[p<<1].rmax=tree[p<<1].sum=tree[p<<1].r-tree[p<<1].l+1;
tree[p<<1|1].maxn=tree[p<<1|1].lmax=tree[p<<1|1].rmax=tree[p<<1|1].sum=tree[p<<1|1].r-tree[p<<1|1].l+1;
tree[p<<1].nsum=tree[p<<1|1].nsum=0;
tree[p<<1].tag=tree[p<<1|1].tag=0;
}
tree[p].tag=-1;
return;
}
void update(int p,int l,int r,bool fl){
if(tree[p].l>=l&&tree[p].r<=r){
if(fl)tree[p].maxn=tree[p].lmax=tree[p].rmax=tree[p].sum=0,tree[p].tag=1,tree[p].nsum=tree[p].r-tree[p].l+1;
else tree[p].maxn=tree[p].lmax=tree[p].rmax=tree[p].sum=tree[p].r-tree[p].l+1,tree[p].nsum=tree[p].tag=0;
return;
}
pushdown(p);
int mid=tree[p].l+tree[p].r>>1;
if(l<=mid)update(p<<1,l,r,fl);
if(r>mid)update(p<<1|1,l,r,fl);
push_up(p);
return;
}
node qry(int p,int l,int r){
if(tree[p].l>=l&&tree[p].r<=r)return tree[p];
node a,b,ret;
bool fl=0;
pushdown(p);
int mid=tree[p].l+tree[p].r>>1;
if(l<=mid)a=qry(p<<1,l,r),fl =1,ret=a;
if(r>mid){
b=qry(p<<1|1,l,r);
if(fl){
ret.nsum=a.nsum+b.nsum;
ret.sum=a.sum+b.sum;
ret.lmax=a.lmax+(a.lmax==a.r-a.l+1?b.lmax:0);
ret.rmax=b.rmax+(b.rmax==b.r-b.l+1?a.rmax:0);
ret.maxn=max(a.maxn,max(b.maxn,a.rmax+b.lmax));
}
else ret=b;
}
return ret;
}
void up(int p,int l,int r,int k){
if(tree[p].l>=l&&tree[p].r<=r&&tree[p].sum<=k){
tree[p].maxn=tree[p].lmax=tree[p].rmax=tree[p].sum=0,tree[p].tag=1,tree[p].nsum=tree[p].r-tree[p].l+1;
return ;
}
pushdown(p);
int mid=tree[p].l+tree[p].r>>1;
int rt=0;
if(l<=mid)rt=qry(1,max(l,tree[p].l),mid).sum,up(p<<1,l,r,min(k,rt));
if((k-rt>0||l>mid)&&r>mid)up(p<<1|1,l,r,l<=mid?k-rt:k);
push_up(p);
return;
}
int n,m;
signed main(){
n=read(),m=read();
build(1,1,n);
while(m--){
int op=read(),x=read(),y=read();
if(op==0)update(1,x,y,0);
if(op==1){
int xx=read(),yy=read();
int kl=qry(1,x,y).nsum;
update(1,x,y,0);
if(kl==0)continue;
up(1,xx,yy,kl);
}
if(op==2)cout<<qry(1,x,y).maxn<<"\n";
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...