李超树求卡常
  • 板块P4983 忘情
  • 楼主AAA404
  • 当前回复0
  • 已保存回复1
  • 发布时间2024/9/20 20:31
  • 上次更新2024/9/20 21:08:39
查看原帖
李超树求卡常
723198
AAA404楼主2024/9/20 20:31

rt,换了一车写法还是过不了

本地测极限数据:

离散化:17s

动态开点:3s

找不到哪里复杂度错了,两次 query 都合并成一次了

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const long long inf=1e18;
int n,m,a[N<<5],g[N],ls[N<<5],rs[N<<5],cnt,maxx;
long long f[N],s[N],P[N],delta;
// vector<long long>v;
// vector<int>used;
struct L{
	long long k,b;
}line[N];
long long calc(int id,int x)
{
	return line[id].k*x+line[id].b;
}
bool Less(int a,int b,int x)
{
	return calc(a,x)<calc(b,x);
}
void insert(int &rt,int l,int r,int id)
{
    if(!rt)rt=++cnt;
	if(!a[rt]){a[rt]=id;return;}
	int mid=l+r>>1;
	if(Less(id,a[rt],mid))swap(a[rt],id);
	if(l==r)return;
	if(Less(id,a[rt],l))insert(ls[rt],l,mid,id);
	if(Less(id,a[rt],r))insert(rs[rt],mid+1,r,id);
}
pair<long long,int> merge(pair<long long,int>a,pair<long long,int>b)
{
	if(a.first==b.first)
	{
		if(g[a.second]<g[b.second])return a;
		return b;
	}
	if(a.first<b.first)return a;
	return b;
}
pair<long long,int> query1(int rt,int l,int r,int x)
{
	if(!rt)return make_pair(inf,0);
	pair<long long,int> res=make_pair(calc(a[rt],x),a[rt]);
	int mid=l+r>>1;
	if(l==r)return res;
	if(x<=mid)res=merge(res,query1(ls[rt],l,mid,x));
	else res=merge(res,query1(rs[rt],mid+1,r,x));
	return res; 
}
bool check(long long val)
{
	for(int i=1;i<=cnt;i++)a[i]=ls[i]=rs[i]=0;
	line[0]={0,inf};
	cnt=1;
	int root=1;
	// insert(1,1,n,0);
	for(int i=1;i<=n;i++)
	{
		auto tmp=query1(1,1,maxx,s[i]);
		f[i]=tmp.first+P[i]+2*s[i]+1+val;
		g[i]=g[tmp.second]+1;
		line[i]={-2*s[i],f[i]+P[i]-2*s[i]};
		insert(root,1,maxx,i);
	}
	// cout<<cnt<<endl;
	return g[n]<=m;
}
char *p1,*p2,buf[10000005];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,10000000,stdin),p1==p2)?EOF:*p1++)
int read(){
int x=0,f=1;char ch=nc();
while(ch<48||ch>57){if(ch=='-')f=-1;ch=nc();}
while(ch>=48&&ch<=57){x=x*10+ch-48,ch=nc();}
return x*f;
}
int main()
{
	clock_t c1=clock();
#ifdef LOCAL
 	freopen("1.in","r",stdin);
 	freopen("1.out","w",stdout);
#endif
    ios::sync_with_stdio(0);
 	cin.tie(0);cout.tie(0);
	n=read(),m=read();
	for(int i=1;i<=n;i++)s[i]=read(),s[i]+=s[i-1],P[i]=s[i]*s[i],maxx=max(1ll*maxx,s[i]);
	long long l=-1e18,r=1e18;
	while(l<r)
	{
		long long mid=l+r>>1;
		// check(mid);
		if(check(mid))r=mid;
		else l=mid+1;
	}
	// delta=0;
	check(l);
	cout<<f[n]-l*m-inf;
	// query2(1,1,maxx,114514);
#ifdef LOCAL
	cerr<<"Time used:"<<clock()-c1<<"ms";
#endif
 	return 0;
}
2024/9/20 20:31
加载中...