【XSY2732】Decalcomania 可持久化线段树 分治

题目描述

  有一个陶瓷瓶周围有 n 个可以印花的位置。第i个与第 i+1 个位置之间的距离为 di ,在第 i 个位置印图案要ti秒。

  机器刚开始在 0 号位置,可以以1单位长度每秒的速度移动。

  一个位置只能印一个图案。

  现在有 m 秒,问你最多能印几个图案。

  保证时间不足以绕陶瓷瓶一圈。

  n100000

题解

  肯定是先往一边移动在移动到另外一边。

  不妨设先往右边移动,那么右边的距离就要 ×2

  求出每边印 i 个印花最少要多少秒。

  然后把两边合并即可。

  考虑怎么求。

  显然印i+1个印花的最优方案所需要移动的最右端点肯定在印 i 个印花的右边。

  证明:考虑反证法。

  设f(i,j)为印 i 个印花且最右端点为j的代价, a(i,j) 为在前 i 个端点印印花所需要的第j短时间。

  设印 i 个印花的最优方案所需要移动的最右端点为j i+1 个的右端点是 k(k<j)

  那么有 f(i,j)<f(i,k),a(j,i+1)<a(k,i+1),f(i+1,j)>f(i+1,k)

  但是前两项加起来是第三项,所以不合法。

  然后就可以分治了。

  设当前要求印 l 个到r个的答案,答案区间为 [sl,sr]

  先求出印 mid=l+r2 个的答案和右端点位置 k ,可以通过枚举右端点得到。

  [l,mid1]的右端点位置在 [sl,k] [mid+1,r] 的右端点位置在 [k,sr]

  然后分治下去即可。

  求前面 i 个位置最小的j个印印花的时间可以通过可持久化线段树得到。

  时间复杂度: O(nlog2n)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int q;
char cc[10000010];
int tt;
int h[100010];
ll rd()
{
    ll s=0;
    int c;
    while((c=cc[tt++])<'0'||c>'9');
    s=c-'0';
    while((c=cc[tt++])>='0'&&c<='9')
        s=s*10+c-'0';
    return s;
}
namespace seg
{
    int ls[4000010];
    int rs[4000010];
    ll s[4000010];
    int sz[4000010];
    int cnt;
    int insert(int p1,int &x,int l,int r)
    {
        int p=++cnt;
        ls[p]=ls[p1];
        rs[p]=rs[p1];
        s[p]=s[p1]+h[x];
        sz[p]=sz[p1]+1;
        if(l==r)
            return p;
        int mid=(l+r)>>1;
        if(x<=mid)
            ls[p]=insert(ls[p],x,l,mid);
        else
            rs[p]=insert(rs[p],x,mid+1,r);
        return p;
    }
    ll query(int p,int x,int l,int r)
    {
        if(l==r)
            return (ll)x*h[l];
        int mid=(l+r)>>1;
        int lsz=sz[ls[p]];
        if(x<=lsz)
            return query(ls[p],x,l,mid);
        return s[ls[p]]+query(rs[p],x-lsz,mid+1,r);
    }
}
int rt[100010];
int n;
ll m;
ll d[100010];
int t[100010];
ll a[100010];
ll f1[100010];
ll f2[100010];
ll g1[100010];
ll g2[100010];
int b[100010];
int c[100010];
int e[100010];
int f[100010];
ll &mm=m;
void gao(int l,int r,int sl,int sr,ll *s)
{
    if(l>r)
        return;
    int mid=(l+r)>>1;
    ll ans=0x3fffffffffffffffll;
    int i;
    int m=sr;
    for(i=sl;i<=sr;i++)
        if(i>=mid&&a[i-1]<=mm)
        {
            ll v=a[i-1]+seg::query(rt[i],mid,0,q);
            if(v<ans)
            {
                ans=v;
                m=i;
            }
        }
    s[mid]=ans;
    gao(l,mid-1,sl,m,s);
    gao(mid+1,r,m,sr,s);
}
void gao(ll *s)
{
    memset(rt,0,sizeof rt);
    seg::cnt=0;
    int i;
    for(i=1;i<=n;i++)
        rt[i]=seg::insert(rt[i-1],c[i],0,q);
    gao(1,n,1,n,s);
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
    freopen("a2.out","w",stdout);
#endif
    fread(cc+1,10000000,1,stdin);
//  scanf("%d%lld",&n,&m);
    n=rd();
    m=rd();
    int i;
    q=0;
    for(i=1;i<=n;i++)
//      scanf("%lld%lld",&d[i],&t[i]);
    {
        d[i]=rd();
        t[i]=rd();
        h[++q]=t[i];
    }
    sort(h+1,h+q+1);
    q=unique(h+1,h+q+1)-h-1;
    for(i=1;i<=n;i++)
        t[i]=lower_bound(h+1,h+q+1,t[i])-h;
    for(i=1;i<=n;i++)
    {
        a[i]=d[i];
        c[i]=t[i];
    }
    for(i=1;i<=n;i++)
        a[i]+=a[i-1];
    gao(f1);
    for(i=1;i<=n;i++)
        a[i]*=2;
    c[1]=0;
    gao(g1);
    reverse(t+2,t+n+1);
    reverse(d+1,d+n+1);
    for(i=1;i<=n;i++)
    {
        a[i]=d[i];
        c[i]=t[i];
    }
    for(i=1;i<=n;i++)
        a[i]+=a[i-1];
    gao(f2);
    for(i=1;i<=n;i++)
        a[i]*=2;
    c[1]=0;
    gao(g2);
    int ans=0;
    for(i=1;i<=n;i++)
        if(f1[i]<=m)
            ans=max(ans,i);
    for(i=1;i<=n;i++)
        if(f2[i]<=m)
            ans=max(ans,i);
    int j;
    j=n;
    for(i=1;i<=n;i++)
    {
        while(j&&f1[i]+g2[j]>m)
            j--;
        if(!j)
            break;
        ans=max(ans,i+j-1);
    }
    j=n;
    for(i=1;i<=n;i++)
    {
        while(j&&f2[i]+g1[j]>m)
            j--;
        if(!j)
            break;
        ans=max(ans,i+j-1);
    }
    printf("%d\n",ans);
    return 0;
}
根据提供的引用内容,你遇到的问题是在发送HTTP POST请求时收到了403 Forbidden的错误。这个错误通常表示你没有权限访问所请求的资源。 要解决这个问题,你可以采取以下步骤: 1. 首先,确保你的请求URL正确,并且你有权限访问该URL。你可以尝试在浏览器中直接访问该URL,看看是否能够成功访问。 2. 如果你确定URL是正确的,并且你有权限访问,那么可能是你的请求中缺少了必要的身份验证信息。你可以检查你的请求头中是否包含了正确的身份验证信息,比如Token或用户名密码。 3. 另外,你还可以检查服务器端的配置,确保你的请求被正确地处理和授权。你可以查看服务器的日志,以了解更多关于403错误的详细信息。 综上所述,当你收到403 Forbidden错误时,你应该首先检查URL和权限,然后确保请求中包含了正确的身份验证信息。如果问题仍然存在,你可以进一步检查服务器端的配置和日志,以找出问题的根本原因。 #### 引用[.reference_title] - *1* [kubeadm init报错10248...(The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz‘ failed)](https://blog.csdn.net/weixin_45969972/article/details/123529966)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [c/c++使用libcurl库做http客户端及封装(HTTP_GET和HTTP_POST)](https://blog.csdn.net/xsy29000/article/details/103181267)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值