zoukankan      html  css  js  c++  java
  • BZOJ 4012 [HNOI2015]开店 (区间修改 永久化标记 主席树)

    讲得好啊
    主席树区间修改了,每一次遇到整区间就打永久化标记(不下传,访问的时候沿路径上的标记算答案)然后returnreturn,那么每修改一次只会访问到lognlogn个节点,再加上每个点要在树链上修改lognlogn次,所以空间复杂度O(nlog2n)O(nlog^2n),实测开O(n50)O(n*50)能过…
    各个sum都要开longlong啊,毁一生

    CODE

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    template<typename T>inline void read(T &num) {
    	char ch; int flg = 1;
    	while((ch=getchar())<'0'||ch>'9')if(ch=='-')flg=-flg;
    	for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
    	num*=flg;
    }
    const int MAXN = 150005;
    const int MAXNN = MAXN*50;
    int n, q, A, fir[MAXN], cnt;
    struct edge { int to, nxt, w; }e[MAXN<<1];
    inline void add(int u, int v, int wt) {
    	e[cnt] = (edge){ v, fir[u], wt }, fir[u] = cnt++;
    	e[cnt] = (edge){ u, fir[v], wt }, fir[v] = cnt++;
    }
    struct node {
    	int x, id;
    	node() {}
    	node(int xx, int ii):x(xx), id(ii){}
    	inline bool operator <(const node &o)const {
    		return x == o.x ? id < o.id : x < o.x;
    	}
    }a[MAXN];
    
    LL sumE[MAXN], dis[MAXN], sumD[MAXN];
    int son[MAXN], sz[MAXN], top[MAXN], tmr, dfn[MAXN], fa[MAXN];
    void dfs(int u, int ff) {
    	fa[u] = ff; sz[u] = 1;
    	for(int i = fir[u], v; ~i; i = e[i].nxt)
    		if((v=e[i].to) != ff) {
    			dis[v] = dis[u] + e[i].w;
    			dfs(v, u), sz[u] += sz[v];
    			if(sz[v] > sz[son[u]]) son[u] = v;
    		}
    }
    void dfs2(int u, int tp) {
    	top[u] = tp; dfn[u] = ++tmr;
    	sumE[tmr] = dis[u] - dis[fa[u]];
    	if(son[u]) dfs2(son[u], tp);
    	for(int i = fir[u], v; ~i; i = e[i].nxt)
    		if((v=e[i].to) != fa[u] && v != son[u])
    			dfs2(v, v);
    }
    int ch[MAXNN][2], tim[MAXNN], tot, rt[MAXN]; LL sum[MAXNN];
    
    inline void Newnode(int i, int p) { ch[i][0] = ch[p][0], ch[i][1] = ch[p][1], sum[i] = sum[p], tim[i] = tim[p]; }
    
    void modify(int &i, int l, int r, int L, int R) {
    	Newnode(++tot, i);
    	if(L == l && r == R) { ++tim[i = tot]; return; }
    	sum[i = tot] += sumE[R] - sumE[L-1];
    	int mid = (l + r) >> 1;
    	if(R <= mid) modify(ch[i][0], l, mid, L, R);
    	else if(L > mid) modify(ch[i][1], mid+1, r, L, R);
    	else modify(ch[i][0], l, mid, L, mid), modify(ch[i][1], mid+1, r, mid+1, R);
    }
    inline void Modify(int &r, int x) { while(x) modify(r, 1, n, dfn[top[x]], dfn[x]), x = fa[top[x]]; }
    LL query(int i, int l, int r, int L, int R) {
    	LL res = (sumE[R] - sumE[L-1]) * tim[i];
    	if(L == l && r == R) return res + sum[i];
    	int mid = (l + r) >> 1;
    	if(R <= mid) return res + query(ch[i][0], l, mid, L, R);
    	else if(L > mid) return res + query(ch[i][1], mid+1, r, L, R);
    	return res + query(ch[i][0], l, mid, L, mid) + query(ch[i][1], mid+1, r, mid+1, R);
    }
    LL Query(int r, int x) { LL res = 0; while(x) res += query(r, 1, n, dfn[top[x]], dfn[x]), x = fa[top[x]]; return res; }
    int main () {
    	read(n), read(q), read(A);
    	for(int i = 1; i <= n; ++i)
    		read(a[i].x), a[i].id = i;
    	sort(a + 1, a + n + 1);
    	memset(fir, -1, sizeof fir);
    	for(int i = 1, x, y, z; i < n; ++i)
    		read(x), read(y), read(z), add(x, y, z);
    	dfs(1, 0), dfs2(1, 1);
    	for(int i = 1; i <= n; ++i)
    		sumE[i] += sumE[i-1], sumD[i] = sumD[i-1] + dis[a[i].id];
    	for(int i = 1; i <= n; ++i) Modify(rt[i]=rt[i-1], a[i].id);
    	LL ans = 0, L, R, x;
    	while(q--) {
    		read(x), read(L), read(R);
    		L = (L + ans) % A, R = (R + ans) % A;
    		if(L > R) swap(L, R);
    		L = lower_bound(a + 1, a + n + 1, node(L, 0)) - a;
    		R = upper_bound(a + 1, a + n + 1, node(R, n)) - a - 1;
    		ans = dis[x] * (R-L+1) + (sumD[R] - sumD[L-1]) - (Query(rt[R], x) - Query(rt[L-1], x)) * 2;
    		printf("%lld
    ", ans);
    	}
    }
    
  • 相关阅读:
    echarts饼状图位置设置
    去除echarts饼状图的引导线
    VS2008里的代码如何格式化
    使用ADO如何获得SQLSERVER 2K的数据库名的列表
    CStdioFile.WriteString无法向文件写入中文
    使用ODBC 数据库 ,运行程序时 出现 “遇到不适当的参数”
    CListCtrl消息及解释
    VC的CListCtrl控件
    找不到Microsoft Access Driver(*.mdb)ODBC驱动程序的安装例程。请重新安装驱动
    WebBrowser 控件-说明
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039377.html
Copyright © 2011-2022 走看看