zoukankan      html  css  js  c++  java
  • [ZJOI2012]网络

    嘟嘟嘟


    今天复习lct,趁着还年轻多写点数据结构。


    首先不得不吐槽一下,题面好长啊……


    通过观察发现,(c leqslant 10)。那么就可以暴力的建10棵lct。
    接下来说下具体做法:

    1.修改点权
    (c)棵lct上都改一遍。
    2.修改边的颜色。
    设原来的颜色为(i),改成(j)。那么相当于在第(i)棵lct上断边,在第(j)棵lct上连边。
    为了记录每一条边的颜色,我开了一个map<pair<int, int>, int>。这样也能很方便的判断这条边是否存在了。
    同时再维护一个cnt数组,cnt[x][i]表示节点(x)颜色为(i)的出边有多少条,这样Error 1就可以判断了。
    至于如何判断Error 2,其实就是判断在第(j)棵lct上(x)(y)是否联通。
    3.查询
    没啥好说的。


    写起来似乎也不难,记得splay的数组开的是两维就行了。
    坑点在于可能会改成相同的颜色,要特判。我虽然想到了,但是忘了这样还得输出Success.,而不是continue……
    改完后又因为后面没加“.”调了半天……咋这么zz呢……

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 1e4 + 5;
    inline ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    inline void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    
    int n, m, c, K;
    int cnt[maxn][12];
    #define pr pair<int, int>
    #define mp make_pair
    map<pr, int> Map;
    
    #define ls t[col][now].ch[0]
    #define rs t[col][now].ch[1]
    struct Tree
    {
      int ch[2], fa;
      int val, Max, rev;
    }t[12][maxn];
    
    In void change(int now, int col)
    {
      swap(ls, rs); t[col][now].rev ^= 1;
    }
    In void pushdown(int now, int col)
    {
      if(t[col][now].rev)
        {
          if(ls) change(ls, col);
          if(rs) change(rs, col);
          t[col][now].rev = 0;
        }
    }
    In void pushup(int now, int col)
    {
      t[col][now].Max = max(max(t[col][ls].Max, t[col][rs].Max), t[col][now].val);
    }
    In bool n_root(int now, int col)
    { 
      return t[col][t[col][now].fa].ch[0] == now || t[col][t[col][now].fa].ch[1] == now;
    }
    In void rotate(int x, int col)
    {
      int y = t[col][x].fa, z = t[col][y].fa, k = (t[col][y].ch[1] == x);
      if(n_root(y, col)) t[col][z].ch[t[col][z].ch[1] == y] = x; t[col][x].fa = z;
      t[col][y].ch[k] = t[col][x].ch[k ^ 1]; t[col][t[col][y].ch[k]].fa = y;
      t[col][x].ch[k ^ 1] = y; t[col][y].fa = x;
      pushup(y, col), pushup(x, col);
    }
    int st[maxn], top = 0;
    In void splay(int x, int col)
    {
      int y = x;
      st[top = 1] = y;
      while(n_root(y, col)) y = t[col][y].fa, st[++top] = y;
      while(top) pushdown(st[top--], col);
      while(n_root(x, col))
        {
          int y = t[col][x].fa, z = t[col][y].fa;
          if(n_root(y, col)) rotate(((t[col][z].ch[0] == y) ^ (t[col][y].ch[0] == x)) ? x : y, col);
          rotate(x, col);
        }
    }
    In void access(int x, int col)
    {
      int y = 0;
      while(x)
        {
          splay(x, col); t[col][x].ch[1] = y;
          pushup(x, col);
          y = x; x = t[col][x].fa;
        }
    }
    In void make_root(int x, int col)
    {
      access(x, col); splay(x, col);
      change(x, col);
    }
    In int find_root(int x, int col)
    {
      access(x, col); splay(x, col);
      while(t[col][x].ch[0]) pushdown(x, col), x = t[col][x].ch[0];
      return x;
    }
    In void split(int x, int y, int col)
    {
      make_root(x, col); access(y, col);
      splay(y, col);
    }
    In bool Link(int x, int y, int col)
    {
      make_root(x, col);
      if(find_root(y, col) == x) return 0;
      t[col][x].fa = y;
      ++cnt[x][col], ++cnt[y][col];
      return 1;
    }
    In void Cut(int x, int y, int col)
    {
      make_root(x, col);
      if(find_root(y, col) == x && t[col][x].fa == y && !t[col][x].ch[1])
      t[col][x].fa = t[col][y].ch[0] = 0, pushup(y, col);
      --cnt[x][col], --cnt[y][col];
    }
    In int query(int x, int y, int col)
    {
      make_root(x, col);
      if(find_root(y, col) ^ x) return -1;
      access(y, col), splay(y, col);
      return t[col][y].Max;
    }
    
    int main()
    {
      //freopen("ha.in", "r", stdin);
      //freopen("ha.out", "w", stdout);
      n = read(), m = read(), c = read(), K = read();
      for(int i = 1; i <= n; ++i)
        {
          int x = read();
          for(int j = 0; j < c; ++j) t[j][i].val = t[j][i].Max = x;
        }
      for(int i = 1; i <= m; ++i)
        {
          int x = read(), y = read(), w = read();
          if(x > y) swap(x, y);
          Map[mp(x, y)] = w;
          Link(x, y, w);
        }
      for(int i = 1; i <= K; ++i)
        {
          int op = read();
          if(op == 0)
    	{
    	  int x = read(), y = read();
    	  for(int j = 0; j < c; ++j) splay(x, j), t[j][x].val = t[j][x].Max = y;
    	}
          else if(op == 1)
    	{
    	  int x = read(), y = read(), w = read();
    	  if(x == y) {continue;}
    	  if(x > y) swap(x, y);
    	  if(!Map.count(mp(x, y))) puts("No such edge.");
    	  else
    	    {
    	      int col = Map[mp(x, y)];
    	      if(col == w) puts("Success.");
    	      else if(cnt[x][w] >= 2 || cnt[y][w] >= 2) puts("Error 1.");
    	      else if(!Link(x, y, w)) puts("Error 2.");
    	      else
    		{
    		  puts("Success.");
    		  Cut(x, y, col);
    		  Map[mp(x, y)] = w;
    		}
    	    }
    	}
          else
    	{
    	  int w = read(), x = read(), y = read();
    	  write(query(x, y, w)), enter;
    	}
        }
      return 0;
    }
    
  • 相关阅读:
    使用树莓派打造远程WEB服务器
    oracle 12c新建pdb实例
    word标题变成黑色方块解决
    idea 报JDBC连接失败原因之一
    maven项目pom.xml需要的一些配置
    Mysql时区无法识别
    数据库报ORA-12514
    win10无法在桌面右键快捷打开个性化设置、显示设置,在任务栏右键无法快捷打开任务栏设置
    Tomcat部署项目时,发布的项目页面部分乱码,且页面渲染文件也是乱码。
    高性能、高稳定性的跨平台MQTT客户端
  • 原文地址:https://www.cnblogs.com/mrclr/p/10490084.html
Copyright © 2011-2022 走看看