代码求调,0pts 左偏树
查看原帖
代码求调,0pts 左偏树
377873
EricWan楼主2023/12/14 15:07
#include <bits/stdc++.h>
#define int long long
#define MAXN 300005
using namespace std;
int n, m, a[MAXN], ls[MAXN], rs[MAXN], uffa[MAXN], died[MAXN], dist[MAXN], tagp[MAXN], tagm[MAXN], root[MAXN], DEFENSE[MAXN], FA[MAXN], OPT[MAXN], VAL[MAXN], bgn[MAXN], knightans[MAXN], cityans[MAXN], DPTH[MAXN];
int dfsgetfa(int x)
{
	if (uffa[x] == x)
		return x;
	return uffa[x] = dfsgetfa(uffa[x]);
}
void pushdown(int id)
{
    a[id] = a[id] * tagm[id] + tagp[id];
    tagm[ls[id]] *= tagm[id];
    tagp[ls[id]] *= tagm[id];
    tagm[rs[id]] *= tagm[id];
    tagp[rs[id]] *= tagm[id];
    tagp[ls[id]] += tagp[id];
    tagp[rs[id]] += tagp[id];
    tagm[id] = 1;
    tagp[id] = 0;
}
int dfsmerge(int x, int y)
{
	if (x == 0) return y;
	if (y == 0) return x;
	if (a[x] > a[y]) return dfsmerge(y, x);
	if (a[x] == a[y] && x > y) return dfsmerge(y, x);
	pushdown(x);
	rs[x] = dfsmerge(rs[x], y);
	if (dist[ls[x]] < dist[rs[x]])
	{
		swap(ls[x], rs[x]);
	}
	dist[x] = dist[rs[x]] + 1;
	return x;
}
int getfa(int x)
{
    if (died[x])
    {
        return -1;
    }
    return dfsgetfa(x);
}
int merge(int x, int y)
{
    if (died[x] || died[y])
    {
        return 0;
    }
    x = dfsgetfa(x);
    y = dfsgetfa(y);
    if (x == y) return x;
    int anc = dfsmerge(x, y);
    uffa[x] = anc;
    uffa[y] = anc;
    return anc;
}
int delroot(int x)
{
    died[x] = 1;
    int anc = dfsmerge(ls[x], rs[x]);
    uffa[anc] = anc;
    uffa[x] = anc;
    return anc;
}
signed main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> DEFENSE[i];
	}
	DPTH[1] = 1;
	for (int i = 2; i <= n; i++)
    {
        cin >> FA[i] >> OPT[i] >> VAL[i];
        DPTH[i] = DPTH[FA[i]] + 1;
    }
	for (int i = 1; i <= m; i++)
	{
		uffa[i] = i;
		dist[i] = 1;
		tagm[i] = 1;
	}
	for (int i = 1; i <= m; i++)
    {
        cin >> a[i] >> bgn[i];
        if (a[i] < DEFENSE[bgn[i]])
        {
        	// cout << i << " D\n";
            knightans[i] = bgn[i];
            continue;
        }
        if (root[bgn[i]] == 0)
        {
            root[bgn[i]] = i;
        }
        else
        {
            root[bgn[i]] = merge(i,root[bgn[i]]);
        }
    }
    /*
    for (int i = 1; i <= n; i++)
    {
        if (root[i] != 0)
        {
            if (OPT[i] == 0)
            {
                tagp[root[i]] += VAL[i];
            }
            else
            {
                tagm[root[i]] *= VAL[i];
                tagp[root[i]] *= VAL[i];
            }
            pushdown(root[i]);
        }
    }
    */
    for (int city = n; city > 1; city--)
    {
        if (OPT[city] == 0)
        {
            tagp[root[city]] += VAL[city];
        }
        else
        {
            tagm[root[city]] *= VAL[city];
            tagp[root[city]] *= VAL[city];
        }
        int fathercity = FA[city];
        if (root[city] != 0) pushdown(root[city]);
        while (root[city] != 0 && a[root[city]] < DEFENSE[fathercity])
        {
        	// cout << city << " " << root[city] << " " << a[root[city]] << " " << fathercity << endl;
            knightans[root[city]] = fathercity;
            root[city] = delroot(root[city]);
            if (root[city] != 0) pushdown(root[city]);
        }
        // if (root[city] != 0) cout << city << " END " << a[root[city]] << " " << root[city] << endl;
        // else cout << city << " AK IOI\n";
        root[fathercity] = merge(root[city],root[fathercity]);
	}
	// cout << "knight die city:\n";
    // for (int i = 1; i <= m; i++)
    // {
        // cout << knightans[i] << endl;
    // }
    for (int i = 1; i <= m; i++)
    {
        cityans[knightans[i]]++;
        knightans[i] = DPTH[bgn[i]] - DPTH[knightans[i]];
    }
	// cout << "city die number:\n";
    for (int i = 1; i <= n; i++)
    {
        cout << cityans[i] << endl;
    }
	// cout << "knight kill city:\n";
    for (int i = 1; i <= m; i++)
    {
        cout << knightans[i] << endl;
    }
	return 0;
}

WA+MLE,MLE 可以以后再压缩,但我的样例过了,却 WA,求调,给我小 hack 也可。

2023/12/14 15:07
加载中...