https://www.luogu.com.cn/problem/P1090
这道题我之前写过一遍过了
后来心血来潮想用块状链表重写
然后就听取WA声一片了
调了半天也没弄明白
这是原来的码:
#include <bits/stdc++.h>
#include <conio.h>
#include <stdlib.h>
#include <unistd.h>
#define N 1000
#define M 50
using namespace std;
bool Debug = 0;
struct NODE
{
long long data[M];
long long next;
long long m;
void init()
{
for (long long i = 0; i < M; i++)
{
data[i] = 0;
}
next = 0;
m = 0;
}
long long Max()
{
return data[m - 1];
}
long long Min()
{
return data[0];
}
void del(long long d)
{
if(Debug)
cout<<"pool del:"<<d<<endl;
for (long long i = d; i < m - 1; i++)
{
data[i] = data[i + 1];
}
m--;
}
void push(long long d)
{
if(Debug)
cout<<"pool push:"<<d<<endl;
if (m == 0)
{
if(Debug)
cout<<"empty push:"<<endl;
data[m] = d;
}
else if (d <= Min())
{
if(Debug)
cout<<"head push:"<<endl;
for (long long i = m; i > 0; i--)
{
data[i] = data[i - 1];
}
data[0] = d;
}
else if (d >= Max())
{
if(Debug)
cout<<"tali push"<<endl;
data[m] = d;
}
else
{
if(Debug)
cout<<"Start searching:\n";
long long l = 0, r = m - 1;
long long mid;
while (l <= r)
{
mid = (l + r) / 2;
if(Debug)
{
cout<<"mid="<<mid<<endl;
cout<<"l="<<l<<endl;
cout<<"r="<<r<<endl;
cout<<"\n";
}
if (data[mid - 1] <= d && d <= data[mid])
{
break;
}
else if (data[mid - 1] > d)
{
r = mid - 1;
}
else
{
l = mid + 1;
}
}
if(Debug)
cout<<"final mid = "<<mid<<endl;
for (long long i = m; i > mid; i--)
{
data[i] = data[i - 1];
}
data[mid] = d;
}
m++;
}
};
struct LINK
{
NODE pool[N];
long long ph;
long long head;
void init()
{
for (long long i = 0; i < N; i++)
{
pool[i].init();
}
ph = 1;
head = 0;
}
void add(long long d)
{
if(Debug)
{
cout<<"add:"<<d<<endl;
}
long long p = pool[d].next;
if (p == 0)
{
return ;
}
for (long long i = 0; i < pool[p].m; i++)
{
pool[d].data[i + pool[d].m] = pool[p].data[i];
}
pool[d].m += pool[p].m;
pool[d].next = pool[p].next;
pool[p].init();
pool[p].next = ph;
ph = p;
}
void del(long long d1, long long d2)
{
if(Debug)
cout<<"del:"<<d1<<","<<d2<<endl;
pool[d1].del(d2);
long long p = pool[d1].next;
if (pool[d1].m + pool[p].m < M)
{
add(d1);
}
}
long long nextp()
{
long long p = ph;
if (pool[ph].next)
{
ph = pool[ph].next;
}
else
{
ph++;
}
return p;
}
void slime(long long d)
{
if(Debug)
cout<<"slime:"<<d<<endl;
long long p = nextp();
long long mid = M / 2;
for (long long i = mid; i < M; i++)
{
pool[p].data[i - mid] = pool[d].data[i];
pool[d].m--;
pool[p].m++;
}
pool[p].next = pool[d].next;
pool[d].next = p;
}
void push(long long d)
{
if(Debug)
cout<<"Push:"<<d<<endl;
if (head == 0)
{
head = nextp();
pool[head].push(d);
}
else
{
long long i;
for (i = head; i != 0; i = pool[i].next)
{
if (pool[i].Max() >= d)
{
if(Debug)
cout<<"Push in "<<i<<endl;
pool[i].push(d);
break;
}
if (pool[i].next == 0)
{
if(Debug)
cout<<"Push in "<<i<<endl;
pool[i].push(d);
break;
}
}
if (pool[i].m >= M)
{
slime(i);
}
}
}
void debug()
{
cout << "————————————" << endl;
for (long long i = head; i != 0; i = pool[i].next)
{
cout << " pool " << i << ":";
for (long long j = 0; j < pool[i].m; j++)
{
cout << pool[i].data[j] << " ";
}
cout << " m:" << pool[i].m << endl;
}
cout << " ph:" << ph << endl;
cout << " head:" << head << endl;
cout << "————————————" <<"\n\n";
}
};
int main()
{
//freopen("P1090_2.in","r",stdin);
LINK a;
a.init();
long long n;
cin >> n;
for (long long i = 1; i <= n; i++)
{
long long e;
cin>>e;
a.push(e);
//if(i >= 818)
// {
// cout<<"\ni : "<<i<<" e="<<e<<endl;
// a.debug();
// Debug = 1;
// }
}
// a.debug();
long long ans = 0;
for (long long i = 1; i < n; i++)
{
//a.debug();
long long A = a.pool[a.head].data[0];
long long B = a.pool[a.head].data[1];
a.del(a.head, 0);
//cout<<"A:"<<A<<" B:"<<B<<endl;
a.del(a.head, 0);
ans += A + B;
a.push(A + B);
}
cout << ans;
return 0;
}
就冲这一堆调试码你就知道我有多凌乱了
然后!
我无意中把主函数的计算部分改了一下
改成了这样:
long long ans = 0;
for (long long i = 1; i < n; i++)
{
//a.debug();
long long A = a.pool[a.head].data[0];
a.del(a.head, 0);
long long B = a.pool[a.head].data[0];
//cout<<"A:"<<A<<" B:"<<B<<endl;
a.del(a.head, 0);
ans += A + B;
a.push(A + B);
}
然后他就过了....过了....
我寻思着块状链表不是保证有序吗
直接取出第一第二再删
和取一个删一个就有区别了?
晕了
希望有大佬能指点一下,不胜感激qwq