社区讨论
求助平衡树TLE
CF817DImbalanced Array参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @m558e338
- 此快照首次捕获于
- 2024/12/26 19:19 去年
- 此快照最后确认于
- 2025/11/04 12:20 4 个月前
由于老师把这道题放在平衡树题单里,所以想到了平衡树的解决方法。
按道理来说复杂度是,不会TLE,但CF上TLE第13个点。
写了FHQ和SPLAY都TLE了。
FHQ:
CPP#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N=1e6+10;
int n,tot=0,Root=0,num=0,ans=0;
struct node
{
int val,num;
}a[N];
bool cmp(node x,node y)
{
return x.val==y.val?x.num<y.num:x.val>y.val;
}
int ran()
{
return rand()%(N-100);
}
struct Node
{
int ch[2],val,size,pri;
}t[N*2];
void update(int id)
{
t[id].size=t[t[id].ch[0]].size+t[t[id].ch[1]].size+1;
}
int NewNode(int val)
{
t[++tot].size=1;
t[tot].val=val;
t[tot].pri=ran();
return tot;
}
void split(int id,int val,int &x,int &y)
{
if(!id){x=y=0; return;}
if(t[id].val<=val)
{
x=id;
split(t[id].ch[1],val,t[id].ch[1],y);
}
else
{
y=id;
split(t[id].ch[0],val,x,t[id].ch[0]);
}
update(id);
return;
}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(t[x].pri<t[y].pri)
{
t[x].ch[1]=merge(t[x].ch[1],y);
update(x); return x;
}
else
{
t[y].ch[0]=merge(x,t[y].ch[0]);
update(y); return y;
}
}
int Rank(int val)
{
int x,y;
split(Root,val,x,y);
int res=t[x].size;
Root=merge(x,y);
return res;
}
int kth(int id,int k)
{
while(1)
{
int lsize=t[t[id].ch[0]].size;
if(lsize+1==k)return t[id].val;
else if(lsize>=k)id=t[id].ch[0];
else id=t[id].ch[1],k-=(lsize+1);
}
}
void insert(int val)
{
++num;
int x,y,id=NewNode(val);
split(Root,val,x,y);
Root=merge(merge(x,id),y);
}
int lst(int val)
{
int rk=Rank(val);
if(rk==1)return 1;
else return kth(Root,rk-1)+1;
}
int nxt(int val)
{
int rk=Rank(val);
if(rk==num)return n;
else return kth(Root,rk+1)-1;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
srand(time(NULL));
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].val;
a[i].num=i;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
{
int l=1,r=n;
insert(a[i].num);
l=lst(a[i].num);
r=nxt(a[i].num);
ans+=(r-a[i].num+1)*(a[i].num-l+1)*a[i].val;
}
Root=0,num=0;
for(int i=n;i>=1;i--)
{
int l=1,r=n;
insert(a[i].num);
l=lst(a[i].num);
r=nxt(a[i].num);
ans-=(r-a[i].num+1)*(a[i].num-l+1)*a[i].val;
}
cout<<ans;
return 0;
}
Splay:
CPP#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 1e6 + 10;
int n, tot = 0, Root = 0, num = 0, ans = 0;
struct node {
int val, num;
} a[N];
bool cmp(node x, node y) {
return x.val == y.val ? x.num < y.num : x.val > y.val;
}
struct Node {
int ch[2], val, size, fa;
} t[N * 2];
void update(int id) {
t[id].size = t[t[id].ch[0]].size + t[t[id].ch[1]].size + 1;
}
int NewNode(int val) {
t[++tot].size = 1;
t[tot].val = val;
t[tot].fa = 0;
return tot;
}
void rotate(int x) {
int y = t[x].fa, z = t[y].fa;
int d = (t[y].ch[1] == x);
t[y].ch[d] = t[x].ch[d ^ 1];
if (t[x].ch[d ^ 1]) t[t[x].ch[d ^ 1]].fa = y;
t[x].ch[d ^ 1] = y;
t[y].fa = x;
t[x].fa = z;
if (z) t[z].ch[t[z].ch[1] == y] = x;
update(y); update(x);
}
void splay(int x, int goal) {
while (t[x].fa != goal) {
int y = t[x].fa, z = t[y].fa;
if (z != goal) {
if ((t[y].ch[1] == x) == (t[z].ch[1] == y)) rotate(y);
else rotate(x);
}
rotate(x);
}
if (!goal) Root = x;
}
void insert(int val) {
++num;
int x = Root, y = 0;
while (x) {
y = x;
if (t[x].val == val) return;
x = t[x].ch[t[x].val < val];
}
int id = NewNode(val);
if (!y) {
Root = id;
return;
}
t[y].ch[t[y].val < val] = id;
t[id].fa = y;
splay(id, 0);
}
int Rank(int val) {
int x = Root, res = 0;
while (x) {
if (t[x].val == val) {
res += t[t[x].ch[0]].size + 1;
splay(x, 0);
return res;
} else if (t[x].val < val) {
res += t[t[x].ch[0]].size + 1;
x = t[x].ch[1];
} else {
x = t[x].ch[0];
}
}
return 0;
}
int kth(int id, int k) {
while (1) {
int lsize = t[t[id].ch[0]].size;
if (lsize + 1 == k) return t[id].val;
else if (lsize >= k) id = t[id].ch[0];
else id = t[id].ch[1], k -= (lsize + 1);
}
}
int lst(int val) {
int rk = Rank(val);
if (rk == 1) return 1;
else return kth(Root, rk - 1) + 1;
}
int nxt(int val) {
int rk = Rank(val);
if (rk == num) return n;
else return kth(Root, rk + 1) - 1;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
srand(time(NULL));
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i].val;
a[i].num = i;
}
sort(a + 1, a + 1 + n, cmp);
for (int i = 1; i <= n; i++) {
int l = 1, r = n;
insert(a[i].num);
l = lst(a[i].num);
r = nxt(a[i].num);
ans += (r - a[i].num + 1) * (a[i].num - l + 1) * a[i].val;
}
Root = 0;
num = 0;
for (int i = n; i >= 1; i--) {
int l = 1, r = n;
insert(a[i].num);
l = lst(a[i].num);
r = nxt(a[i].num);
ans -= (r - a[i].num + 1) * (a[i].num - l + 1) * a[i].val;
}
cout << ans;
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...