[ZJOI 2012] 网络

[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=2816

[算法]

对每种颜色的边建一棵LCT , 维护联通性即可

时间复杂度 : O(C * NlogN ^ 2)

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
const int MAXC = 15;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

int n , m , c , k;
int u[MAXN] , v[MAXN] , w[MAXN] , val[MAXN] , cnt[MAXC][MAXN];
map< pair<int , int> , int> mp;

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}

struct Link_Cut_Tree
{
        struct Node
        {
                int father , son[2] , value , mx;
                bool tag;
        }    a[MAXN];
        inline void init()
        {
                for (int i = 1; i <= n; i++)
                {
                        a[i].father = 0;
                        a[i].son[0] = a[i].son[1] = 0;
                        a[i].value = a[i].mx = val[i];
                        a[i].tag = false;
                }
        }
        inline void pushdown(int x)
        {
                if (a[x].tag)
                {
                        swap(a[x].son[0] , a[x].son[1]);
                        a[a[x].son[0]].tag ^= 1;
                        a[a[x].son[1]].tag ^= 1;
                        a[x].tag = false;
                }
        }
        inline void update(int x)
        {
                a[x].mx = a[x].value;
                if (a[x].son[0]) chkmax(a[x].mx , a[a[x].son[0]].mx);
                if (a[x].son[1]) chkmax(a[x].mx , a[a[x].son[1]].mx);
        }
        inline bool get(int x)
        {
                pushdown(x);
                return a[a[x].father].son[1] == x;
        }
        inline bool nroot(int x)
        {
                return a[a[x].father].son[0] == x || a[a[x].father].son[1] == x;
        }
        inline void rotate(int x)
        {
                int f = a[x].father , g = a[f].father;
                int tmpx = get(x) , tmpf = get(f);
                int w = a[x].son[tmpx ^ 1];
                if (nroot(f)) a[g].son[tmpf] = x;
                a[x].son[tmpx ^ 1] = f;
                a[f].son[tmpx] = w;
                if (w) a[w].father = f;
                a[f].father = x;
                a[x].father = g;
                update(f);
        }
        inline void splay(int x)
        {
                int y = x , z = 0;
                static int st[MAXN];
                st[++z] = y;
                while (nroot(y)) st[++z] = y = a[y].father;
                while (z) pushdown(st[z--]);
                while (nroot(x))
                {
                        int y = a[x].father , z = a[y].father;
                        if (nroot(y))
                                rotate((a[z].son[0] == y) ^ (a[y].son[0] == x) ? x : y);
                        rotate(x);
                }
                update(x);
        }
        inline void access(int x)
        {
                for (int y = 0; x; x = a[y = x].father)
                {
                        splay(x);
                        a[x].son[1] = y;
                        update(x);
                }
        }
        inline void make_root(int x)
        {
                access(x);
                splay(x);
                a[x].tag ^= 1;
                pushdown(x);
        }
        inline void link(int x , int y)
        {
                make_root(x);
                if (find_root(y) != x) a[x].father = y;
        }
        inline int find_root(int x)
        {
                access(x);
                splay(x);
                while (a[x].son[0])
                {
                        pushdown(x);
                        x = a[x].son[0];
                }
                return x;
        }
        inline void cut(int x , int y)
        {
                make_root(x);
                if (find_root(y) == x && a[x].father == y && !a[x].son[1])
                {
                        a[x].father = a[y].son[0] = 0;
                        update(y);
                }
        }
        inline void split(int x , int y)
        {
                make_root(x);
                access(y);
                splay(y);
        }
        inline void modify(int x , int y)
        {
                splay(x);
                a[x].value = y;
                update(x);
        }
        inline bool connected(int x , int y)
        {
                return (find_root(x) == find_root(y));
        }
        inline int query(int x , int y)
        {
                split(x , y);
                return a[y].mx;
        }
} T[MAXC];

int main()
{

        read(n); read(m); read(c); read(k);
        for (int i = 1; i <= n; i++) read(val[i]);
        for (int i = 0; i < c; i++) T[i].init();
        for (int i = 1; i <= m; i++)
        {
                read(u[i]); read(v[i]); read(w[i]);
                mp[make_pair(u[i] , v[i])] = mp[make_pair(v[i] , u[i])] = w[i];
                T[w[i]].link(u[i] , v[i]);
                ++cnt[w[i]][u[i]]; ++cnt[w[i]][v[i]];
        }
        for (int i = 1; i <= k; i++)
        {
                int type;
                read(type);
                if (type == 0)
                {
                        int x , y;
                        read(x); read(y);
                        for (int i = 0; i < c; i++) T[i].modify(x , y);
                }    else if (type == 1)
                {
                        int u , v , w;
                        read(u); read(v); read(w);
                        if (!mp.count(make_pair(u , v)))
                        {
                                printf("No such edge.\n");
                                continue;
                        } else
                        {
                                int value = mp[make_pair(u , v)];
                                if (value == w)
                                {
                                        printf("Success.\n");
                                        continue;
                                }
                                if (cnt[w][u] >= 2 || cnt[w][v] >= 2)
                                {
                                        printf("Error 1.\n");
                                        continue;
                                }
                                if (T[w].connected(u , v))
                                {
                                        printf("Error 2.\n");
                                        continue;
                                }
                                printf("Success.\n");
                                T[value].cut(u , v);
                                --cnt[value][u]; --cnt[value][v];
                                T[w].link(u , v);
                                mp[make_pair(u , v)] = mp[make_pair(v , u)] = w;
                                ++cnt[w][u]; ++cnt[w][v];
                        }
                } else
                {
                        int w , u , v;
                        read(w); read(u); read(v);
                        if (!T[w].connected(u , v)) printf("-1\n");
                        else printf("%d\n" , T[w].query(u , v));
                }
        }

        return 0;

}

原文地址:https://www.cnblogs.com/evenbao/p/10159318.html

时间: 2024-10-14 21:31:19

[ZJOI 2012] 网络的相关文章

Windows Server 2008 R2/2012 网络负载平衡NLB相关内容

使用网络负载均衡技术可以实现一些应用程序的可用性和可伸缩性,常用的应用程序有:IIS.防火墙.VPN以及一些关键业务.每一个节点运行应用程序的一个副本.NLB在群集中的多个主机中分发传入的客户端请求.可以动态地添加主机,也可以将所有流量引导到指定的单个主机,这个主机就称为默认主主机.在一个群集中最多支持 32 台计算机. 当计算机意外出现故障或者脱机时,将断开与出现故障或脱机的服务器之间的活动连接.但是,如果您有意关闭主机,则可以在使计算机脱机之前,使用 drainstop 命令处理所有活动的连

关于Windows Server 2012 网络发现启动不了

Windows Server 2012 网络发现启动不了(启动网络发现无法保存) 具体位置在 " 控制面板\网络和 Internet\网络和共享中心\高级共享设置 "点击启动网络发现,点击保存保存后,点击高级共享设备网络共享设备还是关闭的.解决方案:win+r启动运行框,输入services.msc,进入服务控制台去服务里面,把"Function Discovery Resource Publication""SSDP Discovery"&qu

Windows Server 2012 网络负载平衡(NLB)

本次实验是网络负载平衡,也就是两台服务器对外提供相同的服务,访问者访问的是两台服务器虚拟出来的一个地址,当其中任意一台服务器出现问题不能访问的时候,另一台服务器仍然可以继续对外提供服务,不会出现服务无法访问的情况. 大环境的配置如下图. 一般情况下两台服务器会对外提供某些服务,比如WEB之类的,但在实验环境中,为了节约资源,我们就用客户机ping通VIP地址不间断就能达到实验效果了. 下面我们开始配置,首先要在Server01和Server02两台服务器上面安装网络负载平衡角色,添加角色和功能-

数学 ZJOI 2012 数列

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int maxn=110; 6 struct ExtInt{ 7 int a[maxn],len; 8 ExtInt(){ 9 memset(a,0,sizeof(a)); 10 len=1; 11 } 12 void clear(){ 13 memset(a,0,sizeof(a))

BZOJ 2657 ZJOI 2012 旅游(journey) 树的直径

题目大意:给出一个凸多边形的三角剖分图,每一个三角形代表一个城市,现在连接这个图中的两个点,问最多能够经过多少个城市. 思路:浙江都是一帮神么.. 这题给的条件简直是不知所云啊..转化十分巧妙.因为每个凸n边形经过三角剖分之后会出现n - 2个三角形,任意一条边只会成为两个城市的公共边或者整个多边形的边.不难推出两个城市的公共边是n - 3条,也就是说把公共边看成是新图的边的话,就会新图就会构成一颗树.之后就是很水的树的直径了... CODE: #include <map> #include

[ZJOI 2012]灾难

Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过生物的阿米巴告诉小强,草原是一个极其稳定的生态系统.如果蚂蚱灭绝了,小鸟照样可以吃别的虫子,所以一个物种的灭绝并不一定会引发重大的灾难. 我们现在从专业一点的角度来看这个问题.我们用一种叫做食物网的有向图来描述生物之间的关系: 一个食物网有N个点,代表N种生物,如果生物x可以吃生物y,那么从y向x连一

BZOJ 2656 ZJOI 2012 数列(sequence) 高精度+记忆化搜索

题目大意:定义个一序列,f[i] = f[i / 2] (i % 2 == 0);f[i] = f[i / 2] + f[i / 2 + 1] (i % 2 == 1);求这个数列的第m项(m <= 10 ^ 100) 思路:数据范围高精度没跑了.记得之前做过这个题的弱化版,似乎是没有高精度的记忆化搜索,这个题就是加个高精度. CODE: #include <map> #include <cstdio> #include <cstring> #include &l

BZOJ 2815 ZJOI 2012 灾难 动态倍增LCA

题目背景 阿米巴是小强的好朋友. 题目大意 给出一个食物链(拓扑图),定义一个生物所有的食物都灭绝了之后他自己也灭绝了.定义每种生物灭绝之后跟随着它灭绝的生物个数为这个生物的灾难值.求所有生物的灾难值. 思路 看题帽知出题人系列. fhq的题大家也知道,一般都是不可做的.于是我就去看了他的题解,发现这个题还是可做的. 定义一种灭绝树,对于任意一个子树,若这个子树的根节点灭绝,那么子树中的所有点都会灭绝.只要弄出这个树,我们就可以解决问题了. 先加一个超级食物,然后从这个点开始拓扑排序,保证处理到

[ZJOI 2012]数列

Description 题库链接 给你一个数列 \(A\),满足递推公式 \[ A_n\left\{\begin{aligned}&0,&n=0\\&1,&n=1\\&A_\frac{n}{2},&2\mid n\\&A_{\left\lfloor\frac{n}{2}\right\rfloor}+A_{\left\lceil\frac{n}{2}\right\rceil},&\text{else}\end{aligned}\right. \