[BJOI2017] 喷式水战改
1.CF1209G2 Into Blocks (hard version)2.「POJ 3744」Scout YYF I3.记录trick4.洛谷P10936 导弹防御塔5.CF1635E Cars6.P87267.CF633G8.CF1436E
9.[BJOI2017] 喷式水战改
10.「CF407E」k-d-sequence11.「雅礼集训 2017 Day5」珠宝12.AT_jsc2019_final_h Distinct Integers13.CF1430G Yet Another DAG Problem14.[2022CCPC广州] B Ayano and sequences15.[2022CCPC广州] Infection16.[2022CCPC广州] XOR Sum首先看到要插入序列,所以自然地想到平衡树,那么左儿子就是左边的序列,右儿子就是右边的序列,求这个值的朴素算法是dp吧,就是前
code:
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#pragma GCC optimeze(3)
#pragma GCC optimeze(2)
#define PII pair<int, int>
#define pb push_back
#define fi first
#define se second
#define lowbit(x) (x & (-x))
#define inv(x) (qpow(x,mod-2))
using namespace std;
const int N=4e5+10;
double eps=1e-6;
inline int read(){
char ch=getchar();bool f=0;int x=0;
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=1;
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
if(f==1)x=-x;return x;
}
struct node{
int ls,rs,w,siz,a[4],len,al;
int f[5][5];
}tr[N];
int tot,n,root;
void newnode(int&id,int k,int a,int b,int c){
id=++tot;
tr[id].w=rand(),tr[id].siz=1,tr[id].al=tr[id].len=k;
tr[id].a[1]=a,tr[id].a[2]=b,tr[id].a[3]=c;
tr[id].f[1][1]=tr[id].a[1]*k;
tr[id].f[2][2]=tr[id].a[2]*k;
tr[id].f[3][3]=tr[id].a[3]*k;
tr[id].f[4][4]=tr[id].a[1]*k;
for(int i=1;i<=3;i++){
for(int j=i+1;j<=4;j++){
tr[id].f[i][j]=max(tr[id].f[i][j-1],tr[id].f[j][j]);
}
}
}
void pushup(int p){
memset(tr[p].f,0,sizeof tr[p].f);
int ok[5]={};
int ls=tr[p].ls,rs=tr[p].rs;
ok[1]=tr[p].f[1][1]=tr[p].a[1]*tr[p].len;
ok[2]=tr[p].f[2][2]=tr[p].a[2]*tr[p].len;
ok[3]=tr[p].f[3][3]=tr[p].a[3]*tr[p].len;
ok[4]=tr[p].f[4][4]=tr[p].a[1]*tr[p].len;
for(int i=1;i<=4;i++)tr[p].f[i][i]+=tr[ls].f[i][i]+tr[rs].f[i][i];
for(int len=2;len<=4;len++){
for(int l=1;l+len-1<=4;l++){
int r=l+len-1;
for(int i=l;i<=r;i++){
tr[p].f[l][r]=max(tr[p].f[l][r],tr[ls].f[l][i]+ok[i]+tr[rs].f[i][r]);
}
}
}
tr[p].siz=tr[ls].siz+tr[rs].siz+1;
tr[p].al=tr[ls].al+tr[rs].al+tr[p].len;
}
int merge(int x,int y){
if(!x||!y)return x|y;
if(tr[x].w<tr[y].w){
tr[x].rs=merge(tr[x].rs,y);
pushup(x);
return x;
}
tr[y].ls=merge(x,tr[y].ls);
pushup(y);
return y;
}
void split(int id,int cnt,int&x,int&y){
if(!id){
x=y=0;
return;
}
if(tr[tr[id].ls].al+tr[id].len<cnt){
x=id;
split(tr[id].rs,cnt-(tr[tr[id].ls].al+tr[id].len),tr[x].rs,y);
pushup(x);
}
else{
y=id;
split(tr[y].ls,cnt,x,tr[y].ls);
pushup(y);
}
}
void split2(int id,int k,int&x,int &y){
if(!id){
x=y=0;
return;
}
if(tr[tr[id].ls].siz+1<=k){
x=id;
split2(tr[id].rs,k-tr[tr[id].ls].siz-1,tr[x].rs,y);
pushup(x);
}
else{
y=id;
split2(tr[y].ls,k,x,tr[y].ls);
pushup(y);
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
srand(time(0));
cin>>n;
int lst=0;
while(n--){
int p,a,b,c,x;
cin>>p>>a>>b>>c>>x;
int T1,T2,T3;
split(root,p,T1,T2);
if(tr[T1].al!=p){
split2(T2,1,T3,T2);
int a=tr[T3].a[1],b=tr[T3].a[2],c=tr[T3].a[3],len=tr[T3].len;
int x,xx;
newnode(x,p-tr[T1].al,a,b,c);
newnode(xx,len-(p-tr[T1].al),a,b,c);
T1=merge(T1,x),T2=merge(xx,T2);
}
int t;newnode(t,x,a,b,c);
root=merge(merge(T1,t),T2);
int ans=tr[root].f[1][4];
cout<<ans-lst<<'\n';
lst=ans;
}
return 0;
}
本文作者:Xdik
本文链接:https://www.cnblogs.com/Xdik/p/18709451
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!