zoukankan      html  css  js  c++  java
  • 洛谷p4211 [LNOI2014] LCA

    [LNOI2014] LCA

    题面

    洛谷

    题解

    水题。
    对于一个区间([l,r])的答案。
    我们把它差分成([1,r] - [1,l - 1])
    然后因为右端点是固定的,用树剖+只有1个端点的莫队就解决了...
    你谷恶评实在太严重了。

    #include <bits/stdc++.h>
    
    const int maxn = 5e4 + 10;
    const int mod = 201314;    
    
    template<class t> inline void read(t& res) {
    	res = 0;  char ch = getchar();  bool neg = 0;
    	while (!isdigit(ch))
    		neg |= ch == '-', ch = getchar();
    	while (isdigit(ch))
    		res = (res << 1) + (res << 3) + (ch & 15), ch = getchar();
    	if (neg)
    		res = -res;    
    }
    
    int q, n, m, i, j, k, cntq;     
    int hd[maxn], ver[maxn << 1], nxt[maxn << 1], ans[maxn];        
    struct Questions {
    	int p, z, id; int type;  
    	Questions() { p = z = type = id = 0; }
    	Questions(int _p, int _z, int i, int _t) { p = _p;  z = _z;  id = i;  type = _t; }
    	inline friend bool operator < (Questions a, Questions b) { return a.p < b.p; }
    } Q[maxn << 1];
    
    inline void adde(int u, int v) {
    	static int cnte = 0;
    	ver[++cnte] = v;  nxt[cnte] = hd[u];
    	hd[u] = cnte;  return;
    } 
    
    int s[maxn << 2], tag[maxn << 2];   
    inline void push_up(int u) { s[u] = (s[u << 1] + s[u << 1 | 1]) % mod; }     
    inline void down(int u, int l, int r, int v) { s[u] += (r - l + 1) * v;  tag[u] += v; }
    inline void push_down(int u, int l, int r) {
    	int mid = (l + r) >> 1;
    	down(u << 1, l, mid, tag[u]);
    	down(u << 1 | 1, mid + 1, r, tag[u]);
    	tag[u] = 0;   
    }
    void segt_modify(int ml, int mr, int l, int r, int u, int v) {     
    //	printf("%d %d %d %d %d %d
    ", ml, mr, l, r, u, v);      
    	if (ml <= l && r <= mr)
    		return s[u] += (r - l + 1) * v, tag[u] += v, void();
    	int mid = (l + r) >> 1;
    	push_down(u, l, r);
    	if (ml <= mid)
    		segt_modify(ml, mr, l, mid, u << 1, v);
    	if (mid < mr)
    		segt_modify(ml, mr, mid + 1, r, u << 1 | 1, v);
    	push_up(u);
    }
    int segt_query(int ql, int qr, int l, int r, int u) {
    	if (ql <= l && r <= qr)
    		return s[u];
    	int mid = (l + r) >> 1, res = 0;
    	push_down(u, l, r);
    	if (ql <= mid)
    		res += segt_query(ql, qr, l, mid, u << 1) % mod;
    	res %= mod;  
    	if (mid < qr)
    		res += segt_query(ql, qr, mid + 1, r, u << 1 | 1) % mod;
    	res %= mod;   
    	return res;    
    }
    
    namespace Tree_Chain {
    int hsn[maxn], sz[maxn], dep[maxn], fa[maxn], top[maxn];
    int dfn[maxn], tim;      
    void dfs1(int u, int pa) {
    	dep[u] = dep[pa] + 1;
    	fa[u] = pa;
    	sz[u] = 1;
    	for (int i = hd[u]; ~i; i = nxt[i]) {
    		int v = ver[i];
    		if (v == pa)
    			continue;
    		dfs1(v, u);
    		sz[u] += sz[v];
    		if (sz[v] > sz[ hsn[u] ])
    			hsn[u] = v;
    	}
    }
    void dfs2(int u, int up) {
    	top[u] = up;  dfn[u] = ++tim;
    	if (hsn[u])
    		dfs2(hsn[u], up);     
    	for (int i = hd[u]; ~i; i = nxt[i]) {
    		int v = ver[i];
    		if (v == fa[u] || v == hsn[u])
    			continue;
    		dfs2(v, v);     
    	}
    }
    void modify(int u, int v, int val) {
    	while (top[u] != top[v]) {
    		if(dep[ top[u] ] < dep[ top[v] ])
    			std::swap(u, v);  
    		segt_modify(dfn[ top[u] ], dfn[u], 1, n, 1, val);
    		u = fa[ top[u] ];
    	}
    	if (dep[u] > dep[v])
    		std::swap(u, v);
    	segt_modify(dfn[u], dfn[v], 1, n, 1, val);  
    }
    int query(int u, int v) {
    	int res = 0;  
    	while (top[u] != top[v]) {
    		//printf("%d %d
    ", u, v);
    		if (dep[ top[u] ] < dep[ top[v] ])
    			std::swap(u, v);
    		res += segt_query(dfn[ top[u] ], dfn[u], 1, n, 1) % mod;   
    		res %= mod;
    		u = fa[ top[u] ];
    	}
    	if (dep[u] > dep[v])
    		std::swap(u, v);
    	res += segt_query(dfn[u], dfn[v], 1, n, 1) % mod;
    	res %= mod;
    	return res;    
    }
    }
    
    int main() {
    	memset(hd, -1, sizeof(hd));  
    	read(n);  read(q);
    	for (int i = 2, p; i <= n; i++)
    		read(p), p++, adde(p, i), adde(i, p);
    	Tree_Chain::dfs1(1, 0);   
    	Tree_Chain::dfs2(1, 1);
    	for (int i = 1, l, r, z; i <= q; i++) {
    		read(l);  read(r);  read(z);  z++;      
    		Q[++cntq] = Questions(l, z, i, -1);
    		Q[++cntq] = Questions(r + 1, z, i, 1);   
    	}
    	std::sort(Q + 1, Q + cntq + 1);
    	int p = 1;
    	for (int i = 1; i <= cntq; i++) {
    		while (p <= Q[i].p)
    			Tree_Chain::modify(1, p++, 1);  
    		ans[ Q[i].id ] += Tree_Chain::query(1, Q[i].z) * Q[i].type;  
    	}
    	for (int i = 1; i <= q; i++)
    		printf("%d
    ", (ans[i] + mod) % mod);
    	return 0;    
    }
    
  • 相关阅读:
    WebGL-四之二
    WebGL-四之一
    mybatis中批量更新的问题
    nginx+tpmcat+redis实现session共享
    myeclipse快捷方式汇总
    StringBuffer的append方法比“+”高效
    《Thinking in Java》 And 《Effective Java》啃起来
    JAVA链表中迭代器的实现
    myeclipse从SVN检出项目报错
    C#中清空ListView中的数据
  • 原文地址:https://www.cnblogs.com/Sai0511/p/11382294.html
Copyright © 2011-2022 走看看