1 条题解

  • 0
    @ 2025-4-16 16:35:03

    这题的题意是动态中位数维护,我们可以开小根堆和大根堆来维护中位数,中位数位于小根堆顶 toptop ,并且分别记录小根堆和大根堆内数的个数为 cnt1cnt1cnt2cnt2 ,数值的总和为 sum1sum1sum2sum2 ,那么每次查询的结果为:

    ans=(sum1cnt1top)+(cnt2topsum2)ans=(sum1-cnt1*top)+(cnt2*top-sum2)

    时间复杂度:O(nlogn)O(nlogn)

    #define int long long
    #define endl "\n"
    
    const int maxn = 5e5 + 10;
    int n, sum1, sum2, ans;
    multiset<int> q1, q2;
    
    void check()
    {
    	if (q1.size() > q2.size() + 1)
    	{
    		int val = *q1.begin();
    		q1.erase(q1.begin()), sum1 += val;
    		q2.insert(-val), sum2 -= val;
    	}
    
    	if (q1.size() < q2.size())
    	{
    		int val = *q2.begin();
    		q2.erase(q2.begin()), sum2 -= val;
    		q1.insert(-val), sum1 += val;
    	}
    }
    
    void solve()
    {
    	cin >> n;
    	sum1 = sum2 = ans = 0;
    	while (n--)
    	{
    		string opt;
    		int x;
    		cin >> opt;
    		if (opt[0] == 'a')
    		{
    			cin >> x;
    			if (q1.empty() || x < -*q1.begin())
    				q1.insert(-x), sum1 += x;
    			else
    				q2.insert(x), sum2 += x;
    			check();
    		}
    		else if (opt[0] == 'r')
    		{
    			cin >> x;
    			if (q1.find(-x) != q1.end())
    				q1.erase(q1.find(-x)), sum1 -= x;
    			else if (q2.find(x) != q2.end())
    				q2.erase(q2.find(x)), sum2 -= x;
    			check();
    		}
    		else
    		{
                 if (q1.empty()) cout << 0 << endl;
    			else cout << (q1.size() * (-*q1.begin()) - sum1) + (sum2 - q2.size() * (-*q1.begin())) << endl;
    		}
    	}
    }
    
    • 1

    信息

    ID
    8
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    5
    已通过
    1
    上传者