A[洛谷P5787]无向图,每条边有一个出现时段,求每个单位时段图是否是二分图。
B[洛谷P5227]无向图,询问删除一个边集后是否连通。
C[洛谷P3733]连通无向图,边有权,加边、修改(增加的边的)边权、删除(增加的边),求边权异或和最大的环的边权异或和。
D[CF981E]初始全零的n项数列,给定若干区间加的操作,从中任意选出一个子集,求操作后数列的最大值在1,2,...,n中的可能值。(n≤104)
E[CF603E]无向图,初始没有边,依次加边,边有权,求问是否存在一个边集使得每个点的度均为奇数,如果有,最小化边集内边权最大值。
F[洛谷P4097]维护一个二维平面,支持插入一条线段,询问与某条竖直线相交的所有线段中交点纵坐标最大的一条。
G[洛谷P4027]给定两种金券在n天内的单价及初始钱数,每一天可以将所有的钱兑换两种金券(两种金券的比例给定),或者卖掉所有金券。求n天后的最大钱数。
H[CF932F]一棵树,点有两个权值a,b。从一个点u可以走到它子树内的点v,代价为aubv。求每个点到达某个叶子结点的最小代价。
I[洛谷P4655]一个数列,可以删去一些数(开头,结尾除外),代价是保留下的数差分数列的平方和加上每个删除的数的代价(给定),求最小代价。
J[洛谷P4314]维护一个数列,支持区间加,区间覆盖,区间最大值询问,区间历史最大值询问。
K[洛谷P4198]给定若干条形如(x,0)∼(x,y)的线段,求从(0,0)看去,能看到多少条线段。
线段树分治:将每个操作的影响范围拍到线段树上,然后dfs线段树,统计沿途贡献,在叶子结点记录答案。
A用扩展域的并查集维护,只要用按秩合并、支持删除的并查集即可。
B先算出每条边存在的时间段,丢到线段树上,然后用可撤销的并查集维护。
C用线性基维护。
D容易发现只用考虑这样的子集:其中所有区间有公共点。所以把给定的操作丢到线段树上,在叶子结点用bitset做DP。
E首先发现边集存在等价于每个连通块的点数都是偶数。然后按照边权从小到大加边,在叶子结点往前找到第一个合乎条件的位置,将这些边起作用的范围定为其加入时间到该叶子结点的时间即可。
李超线段树:用线段树维护线段(莫名合理)。每个结点的懒惰标记是一条在该区间中点最优的线段,修改时每次更新都往下搜,至多只有一侧的标记需要更新;单点询问时累计路径上的所有标记。
F模板。
G李超线段树维护斜率优化DP。
H从下往上DP,然后用李超线段树优化。使用李超线段树合并。
I很好写的DP。
J线段树维护历史版本,见oiwiki。
K线段树维护单调栈。要求斜率单调递增,合并时向下递归,只会访问一侧。
线段树还是太灵活了。
点击查看A题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| const int N=2e5+5; |
| int n,m,k,ans[N]; |
| struct edge{int u,v;}; |
| struct disjoint_set{ |
| int fa[N<<1],sz[N<<1],st[N<<2][2],top; |
| void init(){for(int i=1;i<=n*2;i++)fa[i]=i,sz[i]=1;} |
| int find(int x){return (fa[x]==x?x:find(fa[x]));} |
| void Union(int x,int y){ |
| int u=find(x),v=find(y); |
| if(u==v)return; |
| if(sz[u]<sz[v])swap(u,v); |
| sz[u]+=sz[v];fa[v]=u; |
| st[++top][0]=u;st[top][1]=v; |
| } |
| void remove(){ |
| int u=st[top][0],v=st[top][1];--top; |
| sz[u]-=sz[v];fa[v]=v; |
| } |
| }S; |
| struct node{int l,r;vector<edge> e;}tr[N<<2]; |
| void build(int p,int l,int r){ |
| tr[p].l=l;tr[p].r=r; |
| if(l==r)return; |
| int mid=l+r>>1; |
| build(p<<1,l,mid); |
| build(p<<1|1,mid+1,r); |
| } |
| void modify(int p,int l,int r,edge x){ |
| if(tr[p].l>=l&&tr[p].r<=r){tr[p].e.push_back(x);return;} |
| if(l<=tr[p<<1].r)modify(p<<1,l,r,x); |
| if(r>=tr[p<<1|1].l)modify(p<<1|1,l,r,x); |
| } |
| void dfs(int p){ |
| int flag=1,tim=S.top; |
| for(auto x:tr[p].e){ |
| if(S.find(x.u)==S.find(x.v)){ |
| for(int i=tr[p].l;i<=tr[p].r;i++) |
| printf("No\n"); |
| flag=0;break; |
| } |
| S.Union(x.u+n,x.v);S.Union(x.u,x.v+n); |
| } |
| if(flag){ |
| if(tr[p].l==tr[p].r)printf("Yes\n"); |
| else dfs(p<<1),dfs(p<<1|1); |
| } |
| while(S.top>tim)S.remove(); |
| } |
| int main(){ |
| scanf("%d%d%d",&n,&m,&k); |
| build(1,1,k); |
| for(int i=1,l,r;i<=m;i++){ |
| edge e; |
| scanf("%d%d%d%d",&e.u,&e.v,&l,&r); |
| if(l!=r)modify(1,l+1,r,e); |
| } |
| S.init();dfs(1); |
| return 0; |
| } |
点击查看B题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| const int N=1e5+5; |
| int n,m,k; |
| struct edge{int u,v;}a[N<<1]; |
| struct disjoint_set{ |
| int fa[N],sz[N],st[N][2],top; |
| void init(int n){for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1;} |
| int find(int x){return fa[x]==x?x:find(fa[x]);} |
| void Union(int x,int y){ |
| int u=find(x),v=find(y); |
| if(u==v)return; |
| if(sz[u]<sz[v])swap(u,v); |
| sz[u]+=sz[v];fa[v]=u; |
| st[++top][0]=u;st[top][1]=v; |
| } |
| void remove(){ |
| int u=st[top][0],v=st[top][1];--top; |
| sz[u]-=sz[v];fa[v]=v; |
| } |
| void clear(int tim){while(top>tim)remove();} |
| }S; |
| vector<int> q[N<<1]; |
| struct node{int l,r;vector<int> e;}tr[N<<2]; |
| void build(int p,int l,int r){ |
| tr[p].l=l;tr[p].r=r; |
| if(l==r)return; |
| build(p<<1,l,l+r>>1); |
| build(p<<1|1,(l+r>>1)+1,r); |
| } |
| void modify(int p,int l,int r,int x){ |
| if(tr[p].l>=l&&tr[p].r<=r){ |
| tr[p].e.push_back(x); |
| return; |
| } |
| if(l<=tr[p<<1].r)modify(p<<1,l,r,x); |
| if(r>=tr[p<<1|1].l)modify(p<<1|1,l,r,x); |
| } |
| void dfs(int p){ |
| int tim=S.top; |
| for(auto x:tr[p].e)S.Union(a[x].u,a[x].v); |
| if(tr[p].l==tr[p].r)printf(S.top==n-1?"Connected\n":"Disconnected\n"); |
| else dfs(p<<1),dfs(p<<1|1); |
| S.clear(tim); |
| } |
| int main(){ |
| scanf("%d%d",&n,&m); |
| for(int i=1;i<=m;i++){ |
| scanf("%d%d",&a[i].u,&a[i].v); |
| q[i].push_back(0); |
| } |
| scanf("%d",&k); |
| for(int i=1,c,d;i<=k;i++){ |
| scanf("%d",&c); |
| while(c--){ |
| scanf("%d",&d); |
| q[d].push_back(i); |
| } |
| } |
| build(1,1,k); |
| for(int i=1;i<=m;i++){ |
| q[i].push_back(k+1); |
| for(int j=0;j<q[i].size()-1;j++) |
| if(q[i][j]+1<q[i][j+1])modify(1,q[i][j]+1,q[i][j+1]-1,i); |
| } |
| S.init(n);dfs(1); |
| return 0; |
| } |
点击查看C题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| typedef bitset<1005> BIT; |
| const int N=1005,len=1000; |
| struct linear_base{ |
| BIT p[N];int top,st[N]; |
| void init(){for(int i=0;i<=len;i++)p[i].reset();top=0;} |
| void insert(BIT x){ |
| for(int i=len;i>=0;i--)if(x[i]){ |
| if(p[i].none()){st[++top]=i;p[i]=x;return;} |
| x^=p[i]; |
| } |
| } |
| void query(){ |
| BIT res;res.reset(); |
| for(int i=len;i>=0;i--)if(!res[i])res^=p[i]; |
| for(int i=len,zero=1;i>=0;i--) |
| if(!zero||res[i]){cout<<res[i];zero=0;} |
| cout<<'\n'; |
| } |
| void remove(){p[st[top]].reset();--top;} |
| void clear(int tim){while(top>tim)remove();} |
| }LB; |
| int n,m,q,k,vis[N];BIT dep[N];string op,s; |
| int head[N],nxt[N],ver[N],tot=1,used[N];BIT val[N]; |
| BIT trans(string s){ |
| BIT res; |
| int l=s.size(); |
| for(int i=0;i<l;i++)res[i]=s[l-1-i]-'0'; |
| return res; |
| } |
| void add(int u,int v,string s){ |
| ver[++tot]=v;val[tot]=trans(s); |
| nxt[tot]=head[u];head[u]=tot; |
| } |
| void dfs(int u){ |
| vis[u]=1; |
| for(int i=head[u],v;i;i=nxt[i]) |
| if(!vis[v=ver[i]]){used[i]=used[i^1]=1;dep[v]=dep[u]^val[i];dfs(v);} |
| } |
| struct edge{int u,v,lst;BIT w;}a[N]; |
| vector<BIT> e[N<<2]; |
| void modify(int p,int l,int r,int L,int R,BIT v){ |
| if(l>=L&&r<=R){e[p].push_back(v);return;} |
| int mid=l+r>>1; |
| if(L<=mid)modify(p<<1,l,mid,L,R,v); |
| if(R>mid)modify(p<<1|1,mid+1,r,L,R,v); |
| } |
| void solve(int p,int l,int r){ |
| int tim=LB.top; |
| for(auto x:e[p])LB.insert(x); |
| if(l==r)LB.query(); |
| else{ |
| solve(p<<1,l,l+r>>1); |
| solve(p<<1|1,(l+r>>1)+1,r); |
| } |
| LB.clear(tim); |
| } |
| int main(){ |
| ios::sync_with_stdio(false); |
| cin.tie(0);cout.tie(0); |
| cin>>n>>m>>q; |
| for(int i=1,u,v;i<=m;i++){ |
| cin>>u>>v>>s; |
| add(u,v,s);add(v,u,s); |
| } |
| dfs(1);LB.init(); |
| for(int i=1;i<=m;i++) |
| if(!used[2*i])LB.insert(dep[ver[2*i]]^dep[ver[2*i+1]]^val[2*i]); |
| LB.query(); |
| if(!q)return 0; |
| for(int i=1;i<=q;i++){ |
| cin>>op; |
| if(op[0]=='A'){ |
| ++k;cin>>a[k].u>>a[k].v>>s; |
| a[k].lst=i;a[k].w=trans(s)^dep[a[k].u]^dep[a[k].v]; |
| } |
| else if(op[1]=='h'){ |
| int id;cin>>id>>s; |
| modify(1,1,q,a[id].lst,i-1,a[id].w); |
| a[id].lst=i;a[id].w=trans(s)^dep[a[id].u]^dep[a[id].v]; |
| } |
| else{ |
| int id;cin>>id; |
| modify(1,1,q,a[id].lst,i-1,a[id].w);a[id].lst=-1; |
| } |
| } |
| for(int i=1;i<=k;i++) |
| if(a[i].lst!=-1)modify(1,1,q,a[i].lst,q,a[i].w); |
| solve(1,1,q); |
| return 0; |
| } |
点击查看D题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| const int N=1e4+5; |
| typedef bitset<N> BIT; |
| int n,q,cnt;BIT ans,now; |
| vector<int> e[N<<2]; |
| void modify(int p,int l,int r,int L,int R,int x){ |
| if(l>=L&&r<=R){e[p].push_back(x);return;} |
| int mid=l+r>>1; |
| if(L<=mid)modify(p<<1,l,mid,L,R,x); |
| if(R>mid)modify(p<<1|1,mid+1,r,L,R,x); |
| } |
| void solve(int p,int l,int r){ |
| BIT tmp=now; |
| for(auto x:e[p])now|=(now<<x); |
| if(l==r)ans|=now; |
| else solve(p<<1,l,l+r>>1), |
| solve(p<<1|1,(l+r>>1)+1,r); |
| now=tmp; |
| } |
| int main(){ |
| scanf("%d%d",&n,&q); |
| for(int i=1,l,r,x;i<=q;i++){ |
| scanf("%d%d%d",&l,&r,&x); |
| modify(1,1,n,l,r,x); |
| } |
| now[0]=1;solve(1,1,n); |
| for(int i=1;i<=n;i++)cnt+=ans[i]; |
| printf("%d\n",cnt); |
| for(int i=1;i<=n;i++) |
| if(ans[i])printf("%d ",i); |
| return 0; |
| } |
点击查看E题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| const int N=1e5+5,M=3e5+5; |
| int n,m,k=1,ans[M]; |
| struct edge{int u,v,w,id;}e[M]; |
| bool operator <(edge a,edge b){return a.w<b.w;} |
| struct disjoint_set{ |
| int fa[N],sz[N],cnt,st[M][2],top; |
| void init(int n){cnt=n;for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1;} |
| int find(int x){return (x==fa[x]?x:find(fa[x]));} |
| void Union(int x,int y){ |
| int u=find(x),v=find(y); |
| if(u==v)return; |
| if(sz[u]<sz[v])swap(u,v); |
| if(sz[u]&1)--cnt;if(sz[v]&1)--cnt; |
| sz[u]+=sz[v];fa[v]=u;if(sz[u]&1)++cnt; |
| st[++top][0]=u;st[top][1]=v; |
| } |
| void remove(){ |
| int u=st[top][0],v=st[top][1];--top; |
| if(sz[u]&1)--cnt;sz[u]-=sz[v];fa[v]=v; |
| if(sz[u]&1)++cnt;if(sz[v]&1)++cnt; |
| } |
| void clear(int tim){while(top>tim)remove();} |
| }S; |
| vector<int> q[M<<2]; |
| void modify(int p,int l,int r,int L,int R,int x){ |
| if(l>=L&&r<=R){q[p].push_back(x);return;} |
| int mid=l+r>>1; |
| if(L<=mid)modify(p<<1,l,mid,L,R,x); |
| if(R>mid)modify(p<<1|1,mid+1,r,L,R,x); |
| } |
| void solve(int p,int l,int r){ |
| int tim=S.top; |
| for(auto x:q[p])S.Union(e[x].u,e[x].v); |
| if(l==r){ |
| for(;k<=m&&S.cnt;k++)if(e[k].id<=l){ |
| S.Union(e[k].u,e[k].v); |
| if(e[k].id!=l)modify(1,1,m,e[k].id,l-1,k); |
| } |
| if(S.cnt)ans[l]=-1;else ans[l]=e[k-1].w; |
| } |
| else solve(p<<1|1,(l+r>>1)+1,r), |
| solve(p<<1,l,l+r>>1); |
| S.clear(tim); |
| } |
| int main(){ |
| scanf("%d%d",&n,&m); |
| for(int i=1;i<=m;i++) |
| scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w),e[i].id=i; |
| sort(e+1,e+m+1);S.init(n);solve(1,1,m); |
| for(int i=1;i<=m;i++)printf("%d\n",ans[i]); |
| return 0; |
| } |
点击查看F题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| typedef pair<double,int> pdi; |
| const int N=1e5+5,M=39989,M0=1e9; |
| const double eps=1e-9; |
| int n,cnt,tr[M<<2+10]; |
| struct line{double k,b;}p[N]; |
| double calc(int id,int x){return p[id].b+p[id].k*x;} |
| int cmp(double x,double y){ |
| if(x-y>eps)return 1; |
| if(y-x>eps)return -1; |
| return 0; |
| } |
| void push_down(int p,int l,int r,int u){ |
| int &v=tr[p],mid=l+r>>1; |
| if(cmp(calc(u,mid),calc(v,mid))==1)swap(u,v); |
| int bl=cmp(calc(u,l),calc(v,l)),br=cmp(calc(u,r),calc(v,r)); |
| if(bl==1||(!bl&&u<v))push_down(p<<1,l,mid,u); |
| if(br==1||(!br&&u<v))push_down(p<<1|1,mid+1,r,u); |
| } |
| void modify(int p,int l,int r,int L,int R,int u){ |
| if(l>=L&&r<=R){push_down(p,l,r,u);return;} |
| int mid=l+r>>1; |
| if(L<=mid)modify(p<<1,l,mid,L,R,u); |
| if(R>mid)modify(p<<1|1,mid+1,r,L,R,u); |
| } |
| pdi pmax(pdi x,pdi y){ |
| if(cmp(x.first,y.first)==-1)return y; |
| if(cmp(x.first,y.first)==1)return x; |
| return x.second<y.second?x:y; |
| } |
| pdi query(int p,int l,int r,int x){ |
| if(r<x||x<l)return {0,0}; |
| int mid=l+r>>1;double res=calc(tr[p],x); |
| if(l==r)return {res,tr[p]}; |
| return pmax({res,tr[p]},pmax(query(p<<1,l,mid,x), |
| query(p<<1|1,mid+1,r,x))); |
| } |
| int main(){ |
| scanf("%d",&n); |
| for(int i=1,op,lstans=0;i<=n;i++){ |
| scanf("%d",&op); |
| if(op==0){ |
| int x;scanf("%d",&x); |
| x=(x+lstans-1)%M+1; |
| lstans=query(1,1,M,x).second; |
| printf("%d\n",lstans); |
| } |
| else{ |
| int x0,y0,x1,y1;++cnt; |
| scanf("%d%d%d%d",&x0,&y0,&x1,&y1); |
| x0=(x0+lstans-1)%M+1; |
| x1=(x1+lstans-1)%M+1; |
| y0=(y0+lstans-1)%M0+1; |
| y1=(y1+lstans-1)%M0+1; |
| if(x0>x1)swap(x0,x1),swap(y0,y1); |
| if(x0==x1)p[cnt].k=0,p[cnt].b=max(y0,y1); |
| else p[cnt].k=1.0*(y1-y0)/(x1-x0),p[cnt].b=y0-p[cnt].k*x0; |
| modify(1,1,M,x0,x1,cnt); |
| } |
| } |
| return 0; |
| } |
点击查看G题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| const int N=1e5+5; |
| int n;double a[N],b[N],r[N],x[N],dp[N]; |
| struct line{ |
| double k,b; |
| double f(double x){return k*x+b;} |
| }; |
| struct LCST{ |
| |
| line tr[N<<2]; |
| void push_down(int p,int l,int r,line u){ |
| line &v=tr[p];int mid=l+r>>1; |
| if(u.f(x[mid])>v.f(x[mid]))swap(u,v); |
| if(u.f(x[l])>v.f(x[l]))push_down(p<<1,l,mid,u); |
| if(u.f(x[r])>v.f(x[r]))push_down(p<<1|1,mid+1,r,u); |
| } |
| void modify(int p,int l,int r,int L,int R,line u){ |
| if(l>=L&&r<=R){push_down(p,l,r,u);return;} |
| int mid=l+r>>1; |
| if(L<=mid)modify(p<<1,l,mid,L,R,u); |
| if(R>mid)modify(p<<1|1,mid+1,r,L,R,u); |
| } |
| line query(int p,int l,int r,int v){ |
| if(l==r)return tr[p]; |
| int mid=l+r>>1;line res=tr[p],tmp; |
| if(v<=mid)tmp=query(p<<1,l,mid,v); |
| else tmp=query(p<<1|1,mid+1,r,v); |
| if(tmp.f(x[v])>res.f(x[v]))res=tmp; |
| return res; |
| } |
| }seg; |
| int main(){ |
| scanf("%d%lf",&n,dp); |
| for(int i=1;i<=n;i++) |
| scanf("%lf%lf%lf",a+i,b+i,r+i),x[i]=a[i]/b[i]; |
| sort(x+1,x+n+1); |
| for(int i=1;i<=n;i++){ |
| double t=a[i]/b[i]; |
| int pos=lower_bound(x+1,x+n+1,t)-x; |
| dp[i]=max(dp[i-1],seg.query(1,1,n,pos).f(t)*b[i]); |
| line u;u.b=dp[i]/(a[i]*r[i]+b[i]);u.k=u.b*r[i]; |
| seg.push_down(1,1,n,u); |
| } |
| printf("%.3lf\n",dp[n]); |
| return 0; |
| } |
点击查看H题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| typedef long long ll; |
| const int N=1e5+5; |
| bool mem1; |
| struct line{ |
| ll k,b; |
| ll f(ll x){return k*x+b;} |
| line(ll k0=0,ll b0=1e12){k=k0;b=b0;} |
| }zero; |
| struct LCST{ |
| line tr[N*60];int lc[N*60],rc[N*60],tot; |
| void push_down(int p,int l,int r,line u){ |
| line &v=tr[p];int mid=l+r>>1; |
| if(u.f(mid)<v.f(mid))swap(u,v); |
| if(u.f(l)<v.f(l)){ |
| if(!lc[p])lc[p]=++tot; |
| push_down(lc[p],l,mid,u); |
| } |
| if(u.f(r)<v.f(r)){ |
| if(!rc[p])rc[p]=++tot; |
| push_down(rc[p],mid+1,r,u); |
| } |
| } |
| line query(int p,int l,int r,int x){ |
| if(!p)return zero; |
| if(l==r)return tr[p]; |
| int mid=l+r>>1;line res=tr[p],tmp; |
| if(x<=mid)tmp=query(lc[p],l,mid,x); |
| else tmp=query(rc[p],mid+1,r,x); |
| if(tmp.f(x)<res.f(x))res=tmp; |
| return res; |
| } |
| int merge(int p,int q,int l,int r){ |
| if(!p)return q; |
| if(!q)return p; |
| if(l==r)return tr[p].f(l)<tr[q].f(l)?p:q; |
| int mid=l+r>>1; |
| lc[p]=merge(lc[p],lc[q],l,mid); |
| rc[p]=merge(rc[p],rc[q],mid+1,r); |
| push_down(p,l,r,tr[q]); |
| return p; |
| } |
| }seg; |
| int n,a[N],b[N],root[N];ll dp[N]; |
| int head[N],nxt[N<<1],ver[N<<1],tot; |
| void add(int u,int v){ver[++tot]=v;nxt[tot]=head[u];head[u]=tot;} |
| void dfs(int u,int fa){ |
| root[u]=++seg.tot; |
| if(!nxt[head[u]]&&fa!=-1){ |
| seg.push_down(root[u],-1e5,1e5,{b[u],0}); |
| return; |
| } |
| for(int i=head[u],v;i;i=nxt[i]) |
| if((v=ver[i])!=fa){ |
| dfs(v,u); |
| root[u]=seg.merge(root[u],root[v],-1e5,1e5); |
| } |
| dp[u]=seg.query(root[u],-1e5,1e5,a[u]).f(a[u]); |
| seg.push_down(root[u],-1e5,1e5,{b[u],dp[u]}); |
| } |
| bool mem2; |
| int main(){ |
| scanf("%d",&n); |
| for(int i=1;i<=n;i++)scanf("%d",a+i); |
| for(int i=1;i<=n;i++)scanf("%d",b+i); |
| for(int i=1,u,v;i<n;i++){ |
| scanf("%d%d",&u,&v); |
| add(u,v);add(v,u); |
| } |
| dfs(1,-1); |
| for(int i=1;i<=n;i++)printf("%lld ",dp[i]); |
| return 0; |
| } |
点击查看I题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| typedef long long ll; |
| const int N=1e6+5; |
| const ll INF=1ll<<50; |
| struct line{ |
| ll k,b; |
| ll f(ll x){return k*x+b;} |
| line(ll k0=0,ll b0=-INF){k=k0,b=b0;} |
| }; |
| struct LCST{ |
| line tr[N<<2];int lc[N<<2],rc[N<<2],tot; |
| void push_down(int p,int l,int r,line u){ |
| line &v=tr[p];int mid=l+r>>1; |
| if(u.f(mid)>v.f(mid))swap(u,v); |
| if(u.f(l)>v.f(l)){ |
| if(!lc[p])lc[p]=++tot; |
| push_down(lc[p],l,mid,u); |
| } |
| if(u.f(r)>v.f(r)){ |
| if(!rc[p])rc[p]=++tot; |
| push_down(rc[p],mid+1,r,u); |
| } |
| } |
| ll query(int p,int l,int r,int x){ |
| if(!p)return -INF; |
| if(l==r)return tr[p].f(x); |
| int mid=l+r>>1;ll res=tr[p].f(x); |
| if(x<=mid)res=max(res,query(lc[p],l,mid,x)); |
| else res=max(res,query(rc[p],mid+1,r,x)); |
| return res; |
| } |
| }seg; |
| int n;ll h[N],s[N],dp[N]; |
| int main(){ |
| scanf("%d",&n); |
| for(int i=1;i<=n;i++)scanf("%lld",h+i); |
| for(int i=1,w;i<=n;i++)scanf("%d",&w),s[i]=s[i-1]+w; |
| dp[1]=0;seg.tot=1;seg.push_down(1,0,1e6,{2*h[1],s[1]-h[1]*h[1]}); |
| for(int i=2;i<=n;i++){ |
| dp[i]=s[i-1]+h[i]*h[i]-seg.query(1,0,1e6,h[i]); |
| seg.push_down(1,0,1e6,{2*h[i],s[i]-h[i]*h[i]-dp[i]}); |
| } |
| printf("%lld\n",dp[n]); |
| return 0; |
| } |
点击查看J题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| const int N=1e5+5; |
| int n,m,a[N];char op; |
| struct node{int mx,mxh,tag,tagh,st,sth;}tr[N<<2]; |
| void push_up(int p){ |
| tr[p].mx=max(tr[p<<1].mx,tr[p<<1|1].mx); |
| tr[p].mxh=max(tr[p<<1].mxh,tr[p<<1|1].mxh); |
| } |
| void push_add(int p,int v,int vh){ |
| tr[p].mxh=max(tr[p].mxh,tr[p].mx+vh);tr[p].mx+=v; |
| if(tr[p].st==INT_MIN)tr[p].tagh=max(tr[p].tagh,tr[p].tag+vh),tr[p].tag+=v; |
| else tr[p].sth=max(tr[p].sth,tr[p].st+vh),tr[p].st+=v; |
| } |
| void push_set(int p,int v,int vh){ |
| tr[p].mxh=max(tr[p].mxh,vh);tr[p].mx=v; |
| tr[p].sth=max(tr[p].sth,vh);tr[p].st=v; |
| } |
| void push_down(int p,int l,int r){ |
| if(tr[p].tag||tr[p].tagh){ |
| push_add(p<<1,tr[p].tag,tr[p].tagh); |
| push_add(p<<1|1,tr[p].tag,tr[p].tagh); |
| tr[p].tag=tr[p].tagh=0; |
| } |
| if(tr[p].st!=INT_MIN||tr[p].sth!=INT_MIN){ |
| push_set(p<<1,tr[p].st,tr[p].sth); |
| push_set(p<<1|1,tr[p].st,tr[p].sth); |
| tr[p].st=tr[p].sth=INT_MIN; |
| } |
| } |
| #define mid (l+r>>1) |
| void build(int p,int l,int r){ |
| tr[p].st=tr[p].sth=INT_MIN; |
| if(l==r){tr[p].mx=tr[p].mxh=a[l];return;} |
| build(p<<1,l,mid); |
| build(p<<1|1,mid+1,r); |
| push_up(p); |
| } |
| void madd(int p,int l,int r,int L,int R,int v){ |
| if(l>=L&&r<=R){push_add(p,v,max(v,0));return;} |
| push_down(p,l,r); |
| if(L<=mid)madd(p<<1,l,mid,L,R,v); |
| if(R>mid)madd(p<<1|1,mid+1,r,L,R,v); |
| push_up(p); |
| } |
| void mset(int p,int l,int r,int L,int R,int v){ |
| if(l>=L&&r<=R){push_set(p,v,v);return;} |
| push_down(p,l,r); |
| if(L<=mid)mset(p<<1,l,mid,L,R,v); |
| if(R>mid)mset(p<<1|1,mid+1,r,L,R,v); |
| push_up(p); |
| } |
| int qmax(int p,int l,int r,int L,int R){ |
| if(l>=L&&r<=R)return tr[p].mx; |
| push_down(p,l,r); |
| int res=INT_MIN; |
| if(L<=mid)res=max(qmax(p<<1,l,mid,L,R),res); |
| if(R>mid)res=max(qmax(p<<1|1,mid+1,r,L,R),res); |
| return res; |
| } |
| int qmaxh(int p,int l,int r,int L,int R){ |
| if(l>=L&&r<=R)return tr[p].mxh; |
| push_down(p,l,r); |
| int res=INT_MIN; |
| if(L<=mid)res=max(qmaxh(p<<1,l,mid,L,R),res); |
| if(R>mid)res=max(qmaxh(p<<1|1,mid+1,r,L,R),res); |
| return res; |
| } |
| int main(){ |
| scanf("%d",&n); |
| for(int i=1;i<=n;i++)scanf("%d",a+i); |
| build(1,1,n); |
| scanf("%d",&m); |
| for(int i=1,x,y,z;i<=m;i++){ |
| while(op=getchar(),op!='Q'&&op!='A'&&op!='P'&&op!='C'); |
| switch(op){ |
| case 'Q':{scanf("%d%d",&x,&y);printf("%d\n",qmax(1,1,n,x,y));break;} |
| case 'A':{scanf("%d%d",&x,&y);printf("%d\n",qmaxh(1,1,n,x,y));break;} |
| case 'P':{scanf("%d%d%d",&x,&y,&z);madd(1,1,n,x,y,z);break;} |
| case 'C':{scanf("%d%d%d",&x,&y,&z);mset(1,1,n,x,y,z);break;} |
| } |
| } |
| return 0; |
| } |
点击查看K题代码
| #include<bits/stdc++.h> |
| using namespace std; |
| const int N=1e5+5; |
| int n,m; |
| struct node{double mx;int len;}tr[N<<2]; |
| int query(int p,int l,int r,double x){ |
| if(l==r)return tr[p].mx>x; |
| int mid=l+r>>1; |
| if(tr[p<<1].mx>x)return query(p<<1,l,mid,x)+tr[p<<1|1].len; |
| else return query(p<<1|1,mid+1,r,x); |
| } |
| void modify(int p,int l,int r,int x,double v){ |
| if(l==r){tr[p].mx=v;tr[p].len=1;return;} |
| int mid=l+r>>1; |
| if(x<=mid)modify(p<<1,l,mid,x,v); |
| else modify(p<<1|1,mid+1,r,x,v); |
| tr[p<<1|1].len=query(p<<1|1,mid+1,r,tr[p<<1].mx); |
| tr[p].mx=max(tr[p<<1].mx,tr[p<<1|1].mx); |
| } |
| int main(){ |
| scanf("%d%d",&n,&m); |
| for(int i=1,x,y;i<=m;i++){ |
| scanf("%d%d",&x,&y); |
| modify(1,1,n,x,1.0*y/x); |
| printf("%d\n",query(1,1,n,0)); |
| } |
| return 0; |
| } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析