混乱邪恶
构造题的第一步总是最难想的。
考虑
n
n
n是偶数的情况,否则添加一个
0
0
0。
首先把数从大到小排序,然后相邻的两个数配对,记其差为
s
i
s_i
si。
注意到
n
∈
[
2
3
m
,
m
]
n\in [\frac{2}{3}m,m]
n∈[32m,m],因此
∑
s
i
≤
m
−
n
2
<
n
\sum s_i\le m-\frac{n}{2}<n
∑si≤m−2n<n。
这就很有意思了。也就是说至少存在
n
2
\frac{n}{2}
2n个
1
1
1,同时注意到
s
i
s_i
si最大值不超过
m
−
n
m-n
m−n。
显然
n
2
≥
m
−
n
\frac{n}{2}\ge m-n
2n≥m−n。那么可以设计如下算法:
按
s
i
s_i
si从大到小排序,如果当前
s
u
m
<
0
sum<0
sum<0,那么加上
s
i
s_i
si,如果
s
u
m
≥
0
sum\ge 0
sum≥0那么减去
s
i
s_i
si。
当然本题还有另一种构造方案。具体是让最大值减最小值,这样每次迭代完
∑
s
i
\sum s_i
∑si不超过数的个数的两倍。最后规约到
2
2
2个数的情况即可。
代码:
我信仰什么,我便实现哪种方法。。
鸽子
sb数据结构题
类比
z
k
w
zkw
zkw线段树,可以把
l
→
r
l\to r
l→r的路径提出来。
然后大力重链剖分。具体是每条重链维护两棵线段树,分别维护与这条链相邻的左子树和右子树。(若一个点的左子树不在链上则这个点维护左子树,否则这个点维护右子树)
跳轻链的过程是单点修改+单点查询,直接用数组维护即可。
注意到我维护的是两个不同的方向,所以把两个部分的答案加起来即可。
复杂度
O
(
n
log
2
n
)
O(n\log^2 n)
O(nlog2n)。
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define pb push_back
using namespace std;
int n,m,rt,num,rk[400005];
int ls[400005],rs[400005];
int dfn[400005],siz[400005],son[400005],num2;
int vs[400005],tp[400005],dep[400005],fa[400005];
ll s[1600020];
struct sgt{
ll t[1600020],tag[1600020],siz[1600020];
void add(int p,ll x) {
t[p]+=siz[p]*x,tag[p]+=x;
}
void pushdown(int p) {
if(tag[p]) add(p<<1,tag[p]),add(p<<1|1,tag[p]),tag[p]=0;
}
void ins(int p,int l,int r,int x,int y) {
siz[p]+=y;if(l==r) return;
int mid=l+r>>1;x<=mid?ins(p<<1,l,mid,x,y):ins(p<<1|1,mid+1,r,x,y);
}
void upd(int p,int l,int r,int ql,int qr,ll x) {
if(ql>qr) return;
if(ql<=l&&r<=qr) {
add(p,x);
return;
}int mid=l+r>>1;pushdown(p);
if(ql<=mid) upd(p<<1,l,mid,ql,qr,x);
if(mid<qr) upd(p<<1|1,mid+1,r,ql,qr,x);
t[p]=t[p<<1]+t[p<<1|1];
}
ll qry(int p,int l,int r,int ql,int qr) {
if(ql>qr) return 0;
if(ql<=l&&r<=qr) return t[p];
int mid=l+r>>1;pushdown(p);
if(qr<=mid) return qry(p<<1,l,mid,ql,qr);
if(mid<ql) return qry(p<<1|1,mid+1,r,ql,qr);
return qry(p<<1,l,mid,ql,qr)+qry(p<<1|1,mid+1,r,ql,qr);
}
}T[2];
void upd(int x,ll d) {
s[x]+=d*siz[son[x]];
}
void dfs(int u,int topf) {
fa[u]=topf,dep[u]=dep[topf]+1;
if(!ls[u]) {
siz[u]=1,rk[++num]=u;
return;
}dfs(ls[u],u),dfs(rs[u],u);siz[u]+=siz[ls[u]]+siz[rs[u]];
son[u]=(siz[ls[u]]>siz[rs[u]])?ls[u]:rs[u];
}
void dfs2(int u,int topf) {
dfn[u]=++num2,tp[u]=topf;
if(!ls[u]) return;
if(ls[u]==son[u]) dfs2(ls[u],topf),dfs2(rs[u],rs[u]),T[1].ins(1,1,n,dfn[u],siz[rs[u]]);
else dfs2(rs[u],topf),dfs2(ls[u],ls[u]),T[0].ins(1,1,n,dfn[u],siz[ls[u]]);
}
void modify(int x,int y,ll d) {
int fx=tp[x],fy=tp[y];
while(fx!=fy) {
if(dep[fx]>dep[fy]) {
T[1].upd(1,1,n,dfn[fx],dfn[x]-1,d),x=fa[fx];
if(tp[x]!=tp[y]&&rs[x]==son[x]) {
upd(x,d);
}
}
else {
T[0].upd(1,1,n,dfn[fy],dfn[y]-1,d),y=fa[fy];
if(tp[x]!=tp[y]&&ls[y]==son[y]) {
upd(y,d);
}
}fx=tp[x],fy=tp[y];
}
if(dep[x]>dep[y]) {
T[1].upd(1,1,n,dfn[y]+1,dfn[x]-1,d);
}
else {
T[0].upd(1,1,n,dfn[x]+1,dfn[y]-1,d);
}
}
ll qry(int x,int y) {
int fx=tp[x],fy=tp[y];ll res=0;
while(fx!=fy) {
if(dep[fx]>dep[fy]) {
res+=T[1].qry(1,1,n,dfn[fx],dfn[x]-1),x=fa[fx];
if(tp[x]!=tp[y]&&rs[x]==son[x]) {
res+=s[x];
}
}
else {
res+=T[0].qry(1,1,n,dfn[fy],dfn[y]-1),y=fa[fy];
if(tp[x]!=tp[y]&&ls[y]==son[y]) {
res+=s[y];
}
}fx=tp[x],fy=tp[y];
}
if(dep[x]>dep[y]) {
res+=T[1].qry(1,1,n,dfn[y]+ 1,dfn[x]-1);
}
else {
res+=T[0].qry(1,1,n,dfn[x]+1,dfn[y]-1);
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;memset(vs,-1,sizeof vs);
for(int i=1;i<n;i++) {
cin>>ls[n+i]>>rs[n+i];
vs[ls[n+i]]=0,vs[rs[n+i]]=1;
}for(int i=n+1;i<2*n;i++) {
if(vs[i]==-1) rt=i;
}n=2*n-1;int x=++n,y=++n,z=++n,w=++n;ls[x]=rt,rs[x]=y,ls[z]=w,rs[z]=x;dfs(z,0),dfs2(z,z);
for(int i=1;i<=m;i++) {
int op,l,r,d;
cin>>op>>l>>r;
if(op==1) {
cin>>d;
modify(rk[l],rk[r+2],d);
}
else {
cout<<qry(rk[l],rk[r+2])<<endl;
}
}
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」