0
点赞
收藏
分享

微信扫一扫

GPLT2020L3-2Splay

雪域迷影 2022-04-24 阅读 35
算法
#include<bits/stdc++.h>
using namespace std;
const int N=600010;
#define int long long
struct Node
{
	int s[2], p, v;
	int size; // 记录以当前节点为根的子树的节点总数
	void init(int _v, int _p) {
		v = _v, p = _p;
		size = 1;
	}
}tr[N]; 
void pushup(int u)
{
	tr[u].size = tr[tr[u].s[0]].size + tr[tr[u].s[1]].size + 1;
}

void rotate(int x)
{
	int y = tr[x].p, z = tr[y].p;
	int k = tr[y].s[1] == x;
	tr[z].s[tr[z].s[1] == y] = x, tr[x].p = z;
	tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y;
    tr[x].s[k ^ 1] = y, tr[y].p = x;
    pushup(y), pushup(x);
}

void splay(int x, int k)
{
	while (tr[x].p != k) {
		int y = tr[x].p, z = tr[y].p;
		if (z != k) {
			if ((tr[y].s[1] == x) ^ (tr[z].s[1] == y)) rotate(x);
			else rotate(y);
		}
		rotate(x);
	}
}

int get_k(int k, int u)
{
	swap(k,u);
	while (u) {
		if (tr[tr[u].s[0]].size >= k) u = tr[u].s[0];
		else if (tr[tr[u].s[0]].size + 1 == k) return tr[u].v;
		else k -= tr[tr[u].s[0]].size + 1, u = tr[u].s[1];
	}
	return -1;
}
vector<int>v[N];
int n,q;
struct Q{
	int x1,x2,y1,y2;
}query[N];
int idx=0;
int build(int l, int r, int p, int id)
{
    int mid = l + r >> 1;
	int u = ++ idx;
    tr[u].init(id, p);
	v[id][mid] = u;
    if (l < mid) tr[u].s[0] = build(l, mid - 1, u, id);
    if (mid < r) tr[u].s[1] = build(mid + 1, r, u, id);
    pushup(u);
    return u;
}
signed main()
{
	cin>>n>>q;
	for(int i=1;i<=n;i++)
	{
		v[i].push_back(0);
		v[i].push_back(1e9);
	}
	for(int i=1;i<=q;i++)
	{
		string s;
		cin>>s;
		int x1,x2,y;
		cin>>x1>>x2>>y;
		v[x1].push_back(y);
		v[x2].push_back(y);
		query[i]={x1,x2,y,y};
	}
	for(int i=1;i<=n;i++)
	{
		// ver[i].resize(v[i].size());
		sort(v[i].begin(),v[i].end());
		v[i].erase(unique(v[i].begin(),v[i].end()),v[i].end());
	}
	for(int i=1;i<=q;i++)
	{
		query[i].y1=lower_bound(v[query[i].x1].begin(),v[query[i].x1].end(),query[i].y1)-v[query[i].x1].begin();
		query[i].y2=lower_bound(v[query[i].x2].begin(),v[query[i].x2].end(),query[i].y2)-v[query[i].x2].begin();
	}
	for(int i=1;i<=n;i++)
	{
		build(0,v[i].size()-1,0,i);
	}
	long long res=0;
	for(int i=1;i<=n;i++)
		res+=1ll*i*i;
	for(int i=1;i<=q;i++)
	{
		int x1=query[i].x1;
		int x2=query[i].x2;
		int y1=query[i].y1;
		int y2=query[i].y2;
		int u1=v[x1][y1];
		int u2=v[x2][y2];
		splay(u1,0);
		splay(u2,0);
		pushup(u1);
		pushup(u2);
		int l1=get_k(u1,1);
		int r1=get_k(u1,tr[u1].size);
		int l2=get_k(u2,1);
		int r2=get_k(u2,tr[u2].size);
		res-=1ll*l1*r1;
		res-=1ll*l2*r2;
		res+=1ll*l1*r2;
		res+=1ll*l2*r1;
		tr[tr[u1].s[1]].p=u2;
		tr[tr[u2].s[1]].p=u1;
		swap(tr[u1].s[1],tr[u2].s[1]);
		pushup(u1),pushup(u2);
		cout<<res<<"\n";
	}
	
	return 0;
}
举报

相关推荐

0 条评论