10.16

A 判断完是决策单调性之后决定回来写(埋下伏笔),B 的题面不好看直接跳了,发现 C 是小清新数据结构,一个小时内会了,又断断续续写了三个小时,最后剩 20min 急忙码完 A 的暴力。
60+0+90 鉴定为菜就多练。

A.共享单车

决策单调性板题,\(O(n^2k)\) 暴力,打个表,发现决策单调性,套上来就行了。

B.困难重重

网络流板题,好像比 A 还简单,还好我直接跳了
首先网格图黑白染色,如果 \(A=B\) 和源点或汇点连费用递增的四条边,直接费用流,\(A\neq B\) 就拆点,额外拆出横点和纵点两个点,横连横,纵连纵,第二条边费用为 \(B-A\)

C.简单树题

赛时冲这题,这辈子有了。
赛时状态:思考这一部分怎么实现-->思考另一部分怎么实现-->回想这一部分怎么实现-->实现这一部分-->回想另一部分怎么实现……
你都分块套树了空间还开 \(512MB\) 卡掉我 \(10\) 分,非得把线段树换成树状数组是吧,还好我有 \(\text{short}\)
[LNOI2014] LCA 带边权,带修,强制在线。

题面

给出一棵 \(n\) 个点的树,给出树上每条边的长度。
你需要顺次执行 \(m\) 个操作,操作分为两种:

  • \(1\ x\ y\):将树上的第 \(x\) 条边的长度修改成 \(y\)
  • \(2\ l\ r\ x\):对于当前这棵树,查询编号在 \([l,r]\) 内的所有点到点 \(x\) 的距离之和。

首先选定根,求出每个点到根距离,记为 \(dis_x\)
\(\sum\limits_{i=l}^{r}dis(x,i)=dis_x\times(r-l+1)+\sum\limits_{i=l}^{r}dis_i-2\sum\limits_{i=l}^{r}dis_{LCA(x,i)}\)

分为两部分维护,一部分要维护 \(\sum\limits_{i=l}^{r}dis_i\),每次修改一条边就是对 \(dfn_i\in[dfn_x,dfn_x+siz_x-1]\) 的点进行修改,分块套树状数组解决。另一部分要维护 \(\sum\limits_{i=l}^{r}dis_{LCA(x,i)}\) ,首先求这东西用 [LNOI2014] LCA 中的 Trick,然后分块套线段树维护 \([l,r]\) 进行到根路径加后的线段树,询问时这两部分一拼就好了。

点击查看代码
#include <bits/stdc++.h>
#define fr first
#define se second
#define U unsigned
#define LL long long
#define pb push_back
#define pii pair<int,int>
#define pLi pair<LL,int>
#define pLL pair<LL,LL>
#define __ __int128
#define ld long double
#define VE vector<LL>
#define db double

using namespace std;

inline int read()
{
	int x = 0,f = 1;char ch = getchar();
	while(!isdigit(ch)) (ch == '-') && (f = -1),ch = getchar();
	while(isdigit(ch)) x = x*10+ch-48,ch = getchar();
	return x*f;
}

inline char R()
{
	char ch = getchar();
	while (!islower(ch)) ch = getchar();
	return ch;
}

const int N = 6e4+5,S = 250;
struct Edge{int u,v,w;}E[N];
struct edge{int to,w,pre;}e[N<<1];
int las[N],cnt,dfn[N],top[N],siz[N],dep[N],fa[N],hs[N],d,to[N];
LL dis[N],val[N];

inline void add(int u,int v,int w){e[++cnt] = {v,w,las[u]},las[u] = cnt;}

void D1(int x)
{
	dep[x] = dep[fa[x]]+1,siz[x] = 1;
	for (int i = las[x],y;i;i = e[i].pre)
	{
		if ((y = e[i].to) != fa[x])
		{
			dis[y] = dis[x]+e[i].w,fa[y] = x,D1(y),siz[x] += siz[y];
			if (siz[y] > siz[hs[x]]) hs[x] = y;
		}
	}
}

void D2(int x,int t)
{
	dfn[x] = ++d,top[x] = t;
	if (hs[x]) D2(hs[x],t);
	for (int i = las[x],y;i;i = e[i].pre)
		if ((y = e[i].to) != fa[x] && y != hs[x]) D2(y,y);
}

inline int LCA(int x,int y)
{
	while (top[x] != top[y])
		dep[top[x]] < dep[top[y]] ? y = fa[top[y]] : x = fa[top[x]];
	return dep[x] < dep[y] ? x : y;
}

int bl[N],pos[N],B,n,l1[S],r1[S],rt[S],ls[N*390],rs[N*390],ct;
short laz[N*390],t[N*390];
LL sum[S],s[N*390],c[N];
struct vec
{
	int a[S],siz;LL laz[S];
	void push_back(int x){a[++siz] = x;}
	void A(int i,LL k){while (i <= siz) laz[i] += k,i += i&-i;}
	LL Q(int i){LL res = 0;while(i) res += laz[i],i -= i&-i;return res;}
}ve[S];

void A(int i,LL k){while(i <= n) c[i] += k,i += i&-i;}
LL Q(int i){LL res = 0;while(i) res += c[i],i -= i&-i;return res;}

void down(int l,int r,int i)
{
	int mid = (l+r)>>1;
	if (!ls[i]) ls[i] = ++ct;
	if (!rs[i]) rs[i] = ++ct;
	laz[ls[i]] += laz[i],laz[rs[i]] += laz[i];
	t[ls[i]] += laz[i],t[rs[i]] += laz[i];
	s[ls[i]] += (Q(mid)-Q(l-1))*laz[i],s[rs[i]] += (Q(r)-Q(mid))*laz[i];
	laz[i] = 0;
}

void M1(int l,int r,int L,int R,int &i)
{
	if (!i) i = ++ct;
	if (l >= L && r <= R)
		return (void)(laz[i]++,t[i]++,s[i] += Q(r)-Q(l-1));
	if (laz[i]) down(l,r,i);
	int mid = (l+r)>>1;
	if (L <= mid) M1(l,mid,L,R,ls[i]);
	if (mid+1 <= R) M1(mid+1,r,L,R,rs[i]);
	s[i] = s[ls[i]]+s[rs[i]];
}

void M2(int l,int r,int p,LL k,int &i)
{
	if (!i) i = ++ct;
	if (l == r) return (void)(s[i] += k*t[i]);
	if (laz[i]) down(l,r,i);
	int mid = (l+r)>>1;
	if (p <= mid) M2(l,mid,p,k,ls[i]);
	else M2(mid+1,r,p,k,rs[i]);
	s[i] = s[ls[i]]+s[rs[i]];
}

void M3(int x,int id){while(x)M1(1,n,dfn[top[x]],dfn[x],rt[id]),x = fa[top[x]];}

LL Q1(int l,int r,int L,int R,int i)
{
	if (!i) return 0;
	if (l >= L && r <= R) return s[i];
	if (laz[i]) down(l,r,i);
	LL res = 0;int mid = (l+r)>>1;
	if (mid >= L) res += Q1(l,mid,L,R,ls[i]);
	if (mid+1 <= R) res += Q1(mid+1,r,L,R,rs[i]);
	return res;
}

LL Q2(int x,int id)
{
	LL res = 0;
	while (x) res += Q1(1,n,dfn[top[x]],dfn[x],rt[id]),x = fa[top[x]];
	return res;
}

inline void build()
{
	for (int i = 1;i <= n;i++)
		bl[i] = (i-1)/B+1,ve[bl[i]].pb(dfn[i]),
		sum[bl[i]] += dis[i],M3(i,bl[i]);
	for (int i = 1;i <= bl[n];i++)
		sort(ve[i].a+1,ve[i].a+ve[i].siz+1),l1[i] = (i-1)*B+1,r1[i] = min(i*B,n);
	for (int i = 1;i <= bl[n];i++)
		for (int j = 1;j <= ve[i].siz;j++)
			pos[ve[i].a[j]] = j;
}

inline void M(int l,int r,int x,int y)
{
	LL k = y-val[x];
	for (int i = 1;i <= bl[n];i++)
	{
		int L = lower_bound(ve[i].a+1,ve[i].a+ve[i].siz+1,l)-ve[i].a,R = upper_bound(ve[i].a+1,ve[i].a+ve[i].siz+1,r)-ve[i].a;
		sum[i] += 1LL*(R-L)*k,ve[i].A(L,k),ve[i].A(R,-k),M2(1,n,dfn[x],k,rt[i]);
	}
	A(dfn[x],k),val[x] = y;
}

inline LL Q(int l,int r)
{
	LL res = 0;
	if (bl[l] == bl[r]) for (int i = l;i <= r;i++) res += dis[i]+ve[bl[l]].Q(pos[dfn[i]]);
	else
	{
		for (int i = l;i <= r1[bl[l]];i++) res += dis[i]+ve[bl[l]].Q(pos[dfn[i]]);
		for (int i = bl[l]+1;i < bl[r];i++) res += sum[i];
		for (int i = l1[bl[r]];i <= r;i++) res += dis[i]+ve[bl[r]].Q(pos[dfn[i]]);
	}
	return res;
}

LL Q3(int l,int r,int x)
{
	LL res = 0;
	if (bl[l] == bl[r]) for (int i = l,L;i <= r;i++) L = LCA(i,x),res += Q(L,L);
	else
	{
		for (int i = l,L;i <= r1[bl[l]];i++) L = LCA(i,x),res += Q(L,L);
		for (int i = bl[l]+1;i < bl[r];i++) res += Q2(x,i);
		for (int i = l1[bl[r]],L;i <= r;i++) L = LCA(i,x),res += Q(L,L);
	}
	return res;
}

int main()
{
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
	n = read();int m = read(),typ = read();B = sqrt(n)+1;
	for (int i = 1;i < n;i++)
		E[i] = {read(),read(),read()},add(E[i].u,E[i].v,E[i].w),add(E[i].v,E[i].u,E[i].w);
	D1(1),D2(1,1);
	for (int i = 1;i < n;i++)
	{
		if(dep[E[i].u] < dep[E[i].v])  val[E[i].v] = E[i].w,to[i] = E[i].v;
		else val[E[i].u] = E[i].w,to[i] = E[i].u;
	}
	for (int i = 1;i <= n;i++) A(dfn[i],val[i]);
	build();
	int las = 0;
	while (m--)
	{
		char op = R();int l = read()^(las*typ),r = read()^(las*typ);
		if (op == 'm') M(dfn[to[l]],dfn[to[l]]+siz[to[l]]-1,to[l],r);
		else
		{
			int x = read()^(las*typ);
			LL ans = -Q3(l,r,x)*2+Q(x,x)*(r-l+1)+Q(l,r);
			las = ans%n;
			printf("%lld\n",ans);
		}
	}
	return 0;
}
posted @ 2024-10-16 17:18  ZepX_D  阅读(22)  评论(0)    收藏  举报