Solution Set - 线段树
A[洛谷P5787]无向图,每条边有一个出现时段,求每个单位时段图是否是二分图。
B[洛谷P5227]无向图,询问删除一个边集后是否连通。
C[洛谷P3733]连通无向图,边有权,加边、修改(增加的边的)边权、删除(增加的边),求边权异或和最大的环的边权异或和。
D[CF981E]初始全零的\(n\)项数列,给定若干区间加的操作,从中任意选出一个子集,求操作后数列的最大值在\(1,2,...,n\)中的可能值。(\(n\le 10^4\))
E[CF603E]无向图,初始没有边,依次加边,边有权,求问是否存在一个边集使得每个点的度均为奇数,如果有,最小化边集内边权最大值。
F[洛谷P4097]维护一个二维平面,支持插入一条线段,询问与某条竖直线相交的所有线段中交点纵坐标最大的一条。
G[洛谷P4027]给定两种金券在\(n\)天内的单价及初始钱数,每一天可以将所有的钱兑换两种金券(两种金券的比例给定),或者卖掉所有金券。求\(n\)天后的最大钱数。
H[CF932F]一棵树,点有两个权值\(a,b\)。从一个点\(u\)可以走到它子树内的点\(v\),代价为\(a_ub_v\)。求每个点到达某个叶子结点的最小代价。
I[洛谷P4655]一个数列,可以删去一些数(开头,结尾除外),代价是保留下的数差分数列的平方和加上每个删除的数的代价(给定),求最小代价。
J[洛谷P4314]维护一个数列,支持区间加,区间覆盖,区间最大值询问,区间历史最大值询问。
K[洛谷P4198]给定若干条形如\((x,0)\sim (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{
//Li Chao's Segment Tree
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;
}
Solution Set - 线段树的更多相关文章
- Solution -「线段树」题目集合
T1 无聊的数列 来自:Link flag 帖先从水题入手. 首先分析题目,它是以等差数列为原型进行的修改.等差数列一大性质就是其差分数列的值除第一项以外均相等. 于是不难想到使用差分数列进行维护. ...
- 【BZOJ-3165】Segment 李超线段树(标记永久化)
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 368 Solved: 148[Submit][Sta ...
- 【BZOJ-1568】Blue Mary开公司 李超线段树 (标记永久化)
1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 557 Solved: 192[Submit ...
- 【线段树】【CF1083C】 Max Mex
Description 给定一棵有 \(n\) 个点的树,每个节点有点权.所有的点权构成了一个 \(0~\sim~n - 1\) 的排列.有 \(q\) 次操作,每次操作 \(1\) 为交换两个点的点 ...
- 【树状数组】【P3372】 【模板】线段树 1
Description 给定一个长度为 \(n\) 的序列,有 \(m\) 次操作,要求支持区间加和区间求和. Limitation \(1 \leq n,~m \leq 10^5\) 序列元素值域始 ...
- Solution -「洛谷 P5787」「模板」二分图(线段树分治)
\(\mathcal{Description}\) Link. \(n\) 个结点的图,\(m\) 条形如 \((u,v,l,r)\) 的边,表示一条连接 \(u\) 和 \(v\) 的无向 ...
- 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序
3779: 重组病毒 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 224 Solved: 95[Submit][Status][Discuss] ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- 【BZOJ-2653】middle 可持久化线段树 + 二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1298 Solved: 734[Submit][Status][Discu ...
- ZKW线段树
简介 zkw线段树虽然是线段树的另一种写法,但是本质上已经和普通的递归版线段树不一样了,是一种介于树状数组和线段树中间的存在,一些功能上的实现比树状数组多,而且比线段树好写且常数小. 普通线段树采用从 ...
随机推荐
- 线上问题分析之java dump文件生成
一.查看java进程 jps or ps aux | grep java 二.生成dump文件 jmap -dump:live,format=b,file=xxxx.bin 进程ID 三.查看dump ...
- 本周四晚19:00知识赋能第六期第5课丨OpenHarmony WiFi子系统
OpenAtom OpenHarmony(以下简称"OpenHarmony")开源开发者成长计划项目自 2021 年 10 月 24 日上线以来,在开发者中引发高度关注. 成长计划 ...
- C# 介绍、应用领域、入门、语法、输出和注释详解
什么是 C#? C#(发音为"C-Sharp")是一种由 Microsoft 创建的面向对象的编程语言,运行在 .NET Framework 上.源于 C 家族,与流行的语言如 C ...
- #莫队二次离线,根号分治#洛谷 5398 [Ynoi2018] GOSICK
题目 \(m\) 组询问求 \(\sum_{l\leq i,j\leq r}[a_i\bmod a_j==0],n,m,a_i\leq 5\times 10^5\) 分析 设 \(f(l,r,x)\) ...
- Mysql之备份工具
一.备份工具 1. mysqldump mysql服务自带的备份工具:mysqldump备份方式是采用的逻辑备份,其最大的缺陷是备份和恢复速度较慢,如果数据库大于50G,mysqldump备份就不太适 ...
- centos-stream-9 centos9 配置国内yum源 阿里云源
源配置 tips: yum配置文件路径 /etc/yum.repos.d/centos.repo 1.备份源配置 [Very Important!] mv /etc/yum.repos.d/cento ...
- 面向切面编程AOP[一](java 代码详解)
前言 说句实话,在工作中,使用的aop不是特别多,但是特别重要,一般是辅助程序,在现代开发者辅助程序相当重要,比如说我们需要打印一些log,但是我们不可能去卸载我们的业务程序中,因为这太..... 正 ...
- Deep Learning on Graphs: A Survey第五章自动编码论文总结
论文地址:https://arxiv.org/pdf/1812.04202.pdf 最近老师让我们读的一片论文,已经开组会讲完了,我负责的是第五章,图的自动编码,现在再总结一遍,便于后者研读.因为这篇 ...
- 简单介绍 Vue 3.0 项目创建
一.前期转杯 确保电脑上已安装 node.js. 可通过命令 npm --version进行查询,如果展示了版本号,则说明已安装,若提示 npm 不是有内部或外部命令,也不是可运行的程序,则说明未安装 ...
- P7177 [COCI2014-2015#4] MRAVI 题解
思路. 我们知道最初添加的液体越多,那么每个蚂蚁得到的液体也就越多,又因为标签里有深搜,所以可以用 DFS+二分解决(感觉说了一通废话),算是比较常规的一种解法了. 在此题中我们需要魔改一下建树,需在 ...