1 solutions

  • 0
    @ 2025-11-5 18:11:11

    C++ :

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    
    char buffer[BufferSize];
    char *head = buffer + BufferSize;
    const char *tail = head;
    
    #ifndef ONLINE_JUDGE
    #	define nextChar getchar
    #else
    inline char nextChar()
    {
    	if (head == tail)
    	{
    		fread(buffer, 1, BufferSize, stdin);
    		head = buffer;
    	}
    	return *head++;
    }
    #endif
    
    inline int getint()
    {
    	static char c;
    	while ((c = nextChar()) < '0' || c > '9');
    
    	int res = c - '0';
    	while ((c = nextChar()) >= '0' && c <= '9')
    		res = res * 10 + c - '0';
    	return res;
    }
    
    namespace output
    {
    	const int BufferSize = 1 << 21;
    
    	char buffer[BufferSize + 1];
    	char *tail = buffer;
    
    	char s[7];
    	inline void putint(int x)
    	{
    		if (!x)
    			*tail++ = '0';
    		else
    		{
    			char *t = s;
    			while (x > 0)
    				*t++ = x % 10 + '0', x /= 10;
    			while (t-- != s)
    				*tail++ = *t;
    		}
    		*tail++ = '\n';
    	}
    
    	inline void final()
    	{
    		fwrite(buffer, 1, tail - buffer, stdout);
    	}
    }
    using output::putint;
    using output::final;
    
    const int MaxN = 100005;
    const int MaxM = MaxN * 2;
    
    int n, m, nQ = 0;
    
    struct lct_node
    {
    	lct_node *lc, *rc, *fa;
    	int sum;
    	bool up, w;
    
    	inline void update()
    	{
    		sum = up = w;
    		if (lc)
    			sum += lc->sum, up = lc->up;
    		if (rc)
    			sum += rc->sum;
    	}
    
    	inline bool is_root()
    	{
    		return !fa || (fa->lc != this && fa->rc != this);
    	}
    
    	inline void rotate()
    	{
    		lct_node *x = this, *y = fa, *z = y->fa;
    		lct_node *b = x == y->lc ? x->rc : x->lc;
    
    		x->fa = z, y->fa = x;
    		if (b)
    			b->fa = y;
    
    		if (z)
    		{
    			if (z->lc == y)
    				z->lc = x;
    			else if (z->rc == y)
    				z->rc = x;
    		}
    		if (x == y->lc)
    			x->rc = y, y->lc = b;
    		else
    			x->lc = y, y->rc = b;
    
    		y->update();
    	}
    
    	inline void splay()
    	{
    		while (!is_root())
    		{
    			if (!fa->is_root())
    			{
    				if ((fa->lc == this) == (fa->fa->lc == fa))
    					fa->rotate();
    				else
    					rotate();
    			}
    			rotate();
    		}
    		update();
    	}
    
    	inline void access()
    	{
    		for (lct_node *p = this, *q = NULL; p; q = p, p = p->fa)
    		{
    			p->splay(), p->rc = q;
    			p->update();
    		}
    	}
    };
    lct_node lct[MaxM];
    
    inline void lct_link(int u, int v)
    {
    	lct_node *x = lct + u;
    	lct_node *y = lct + v;
    	x->splay(), x->fa = y;
    }
    inline void lct_cut(int u)
    {
    	lct_node *x = lct + u;
    	x->access(), x->splay();
    	x->lc->fa = NULL, x->lc = NULL;
    	x->update();
    }
    inline void lct_modify(int u, bool w)
    {
    	lct_node *x = lct + u;
    	x->w = w, x->update();
    }
    inline int lct_query(int u, int v)
    {
    	int res = 0, edge = 1;
    	lct_node *x = lct + u;
    	lct_node *y = lct + v;
    	x->access(), y->access(), x->splay();
    	x->fa ? res += x->sum, edge &= x->up : 0;
    	x->access(), y->splay();
    	y->fa ? res += y->sum, edge &= y->up : 0;
    	edge ? 0 : res += 2;
    	return res;
    }
    
    struct halfEdge
    {
    	int v;
    	halfEdge *next;
    };
    halfEdge adj_pool[MaxM * 2], *adj_tail = adj_pool;
    halfEdge *add[MaxN], *del[MaxN], *query[MaxN];
    
    inline void addEdge(halfEdge *&adj, int v)
    {
    	adj_tail->v = v, adj_tail->next = adj;
    	adj = adj_tail++;
    }
    
    int vertex_n = 1, ver_n = 2;
    int vertex[MaxM];
    int ver_l[MaxM], ver_r[MaxM];
    int fa[MaxM];
    int qu[MaxM], qv[MaxM];
    
    int outcome[MaxM];
    
    int main()
    {
    	n = getint(), m = getint();
    
    	vertex[1] = ver_l[1] = 1, ver_r[1] = n;
    	while (m--)
    	{
    		int type = getint();
    
    		if (type == 0)
    		{
    			vertex[++vertex_n] = ++ver_n;
    			ver_l[vertex_n] = getint();
    			ver_r[vertex_n] = getint();
    		}
    		else if (type == 1)
    		{
    			int l = getint(), r = getint(), v = getint();
    			l = max(l, ver_l[v]);
    			r = min(r, ver_r[v]);
    			if (l <= r)
    			{
    				fa[++ver_n] = vertex[v];
    				addEdge(add[l], ver_n);
    				addEdge(del[r], ver_n);
    			}
    		}
    		else
    		{
    			int x = getint();
    			addEdge(query[x], ++nQ);
    			qu[nQ] = vertex[getint()];
    			qv[nQ] = vertex[getint()];
    		}
    	}
    
    	for (int u = 2; u <= ver_n; ++u)
    		lct[u].fa = lct + u - 1;
    	lct_modify(2, 1);
    	for (int i = 1; i <= n; ++i)
    	{
    		for (halfEdge *e = add[i]; e; e = e->next)
    		{
    			lct_cut(e->v), lct_modify(e->v, 1);
    			lct_link(e->v, fa[e->v]);
    		}
    
    		for (halfEdge *e = query[i]; e; e = e->next)
    			outcome[e->v] = lct_query(qu[e->v], qv[e->v]);
    
    		for (halfEdge *e = del[i]; e; e = e->next)
    		{
    			lct_cut(e->v), lct_modify(e->v, 0);
    			lct_link(e->v, e->v - 1);
    		}
    	}
    
    	for (int i = 1; i <= nQ; ++i)
    		putint(outcome[i]);
    
    	final();
    	return 0;
    }
    
    • 1

    Information

    ID
    18814
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    (None)
    Tags
    # Submissions
    0
    Accepted
    0
    Uploaded By