zoukankan      html  css  js  c++  java
  • [CF1479D] Odd Mineral Resource

    [题目链接]

    http://codeforces.com/contest/1479/problem/D

    [题解]

    做法 (1) :

    考虑树上莫队 , 维护每种颜色的 (cnt) 数组 , 直接用树状数组 / 线段树这样的带 (log) 数据结构会得到一个复杂度为 (O(N sqrt{N} log(N))) 的做法。 这样显然是不优的 , 考虑均摊 , 将线段树改为分块即可。这样的复杂度为 (O(Nsqrt{N}))

    做法 (2) :

    不妨给每种颜色分配一个 (2 ^ {64}) 以内的随机权值。 记 (f(u , l , r)) 表示从根节点到节点 (u) 路径上颜色种类在 ([l , r]) 区间内的点得权值异或和。 这可以用可持久化线段树轻松维护。 那么

    条路径的权值异或和 (f(u , v , l , r)) 就可以通过四棵线段树异或出。

    考虑二分求解 , 若 (f(u , v , l , r) = 0) , 则退出。 否则在左子树 / 右子树中分别寻找答案。

    这样对于一组询问的正确率为 (1 - 2 ^ {-64})

    那么 (q) 组询问的正确率至少是 :

    (egin{aligned} Prleft[ igwedge_{i=1}^{q} A_i ight] & = 1 - Prleft[ igvee_{i=1}^q ar A_i ight] \ & geq 1 - sum_{i=1}^q Pr[ar A_i] \ & = 1 - sum_{i=1}^q left( 1 - Pr[A_i] ight) \ & geq 1 - sum_{i=1}^q left( 1 - left( 1 - 2^{-64} ight) ight) \ & = 1 - 2^{-64}q, end{aligned})

    故正确率大于 (1 - 2 ^ {44})。 是足以通过这道题的。

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

    #include<bits/stdc++.h>
     
    using namespace std;
     
    typedef long long LL;
     
    #define rep(i , l , r) for (int i = (l); i < (r); ++i)
     
    const int MN = 3e5 + 5 , MM = MN * 40;
     
    typedef unsigned long long ull;
     
    mt19937_64 get_value(355);
     
    int N , M , fa[MN] , size , A[MN] , ans;
    ull key[MM] , sum[MM];
    int lc[MM] , rc[MM] , root[MM];
     
    inline int query(int a , int b , int c , int d , int l , int r , int ql , int qr) {
    	if ((sum[a] ^ sum[b] ^ sum[c] ^ sum[d]) == 0) return -1;
    	if (l == r) return l;
    	int mid = l + r >> 1; int res = -1;
    	if (mid >= ql) {
    		res = query(lc[a] , lc[b] , lc[c] , lc[d] , l , mid , ql , qr);
    		if (res != -1) return res;
    	}
    	if (qr > mid) {
    		res = query(rc[a] , rc[b] , rc[c] , rc[d] , mid + 1 , r , ql , qr);
    		if (res != -1) return res;
    	}
    	return -1;
    }
    inline void add(int &now , int old , int l , int r , int x , ull val) {
    	now = ++size; lc[now] = lc[old] , rc[now] = rc[old];
    	sum[now] = sum[old] ^ val;
    	if (l == r) return;
    	int mid = l + r >> 1;
    	if (mid >= x) add(lc[now] , lc[old] , l , mid , x , val);
    	else add(rc[now] , rc[old] , mid + 1 , r , x , val);
    }
    struct Edge {
    	int to , nxt;
    } E[MN << 1];
     
    int tot , head[MN];
     
    inline void AddEdge(int u , int v) {
    	E[++tot] = (Edge) {v , head[u]};
    	head[u] = tot;
    }
     
    int heavy[MN] , siz[MN] , dep[MN] , top[MN];
     
    inline void dfs1(int x) {
    	add(root[x] , root[fa[x]] , 1 , N , A[x] , key[A[x]]);
    	siz[x] = 1;
    	for (int i = head[x]; i; i = E[i].nxt) {
    		int v = E[i].to; if (v == fa[x]) continue;
    		dep[v] = dep[x] + 1 , fa[v] = x , dfs1(v) , siz[x] += siz[v];
    		if (siz[v] > siz[heavy[x]]) heavy[x] = v;
    	}
    }
    inline void dfs2(int x) {
    	if (heavy[x]) top[heavy[x]] = top[x] , dfs2(heavy[x]);
    	for (int i = head[x]; i; i = E[i].nxt) {
    		int v = E[i].to; if (v == fa[x] || v == heavy[x]) continue;
    		top[v] = v , dfs2(v);
    	}
    }
    inline int lca(int u , int v) {
    	while (top[u] != top[v]) {
    		if (dep[top[u]] < dep[top[v]]) swap(u , v);
    		u = fa[top[u]];
    	}
    	if (dep[u] < dep[v]) swap(u , v);
    	return v;
    }
     
    int main() {
    	 
    	 scanf("%d%d" , &N , &M);
    	 for (int i = 1; i <= N; ++i) scanf("%d" , &A[i]) , key[i] = get_value();
    	 for (int i = 1; i < N; ++i) {
    	 	  int u , v; scanf("%d%d" , &u , &v);
    	 	  AddEdge(u , v) , AddEdge(v , u);
    	 }
    	 dfs1(1); top[1] = 1; dfs2(1);
    	 while (M--) {
    	 	 int u , v , sl , sr; scanf("%d%d%d%d" , &u , &v , &sl , &sr);
    	 	 int LCA = lca(u , v);
    	 	 printf("%d
    " , query(root[u] , root[v] , root[LCA] , root[fa[LCA]] , 1 , N , sl , sr));
    	 }
         return 0;
    }
    
  • 相关阅读:
    kubernetes 中遇见的一些坑(持续更新)
    Docker网络解决方案-Flannel部署记录
    理解Docker :Docker 网络
    全面剖析Redis Cluster原理和应用
    python发送钉钉机器人脚本
    centos 7 部署LDAP服务
    zabbix 同步ldap帐号脚本
    zabbix TCP 连接数监控
    WebDriver基本操作入门及UI自动化练手页面
    Jmeter使用入门
  • 原文地址:https://www.cnblogs.com/evenbao/p/14441266.html
Copyright © 2011-2022 走看看