P3178 WA0 求调
  • 板块学术版
  • 楼主hanser520
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/3/19 21:38
  • 上次更新2024/3/20 12:00:01
查看原帖
P3178 WA0 求调
661421
hanser520楼主2024/3/19 21:38

第一版RE0 REcode

#include<bits/stdc++.h>
#define p1 (p << 1)
#define p2 ((p << 1) + 1)
using namespace std;
typedef long long ll;
inline ll read(){
    ll x = 0, f = 1;char ch = getchar();
    while(ch < '0'||ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    return x*f;
}
void write(ll x){
    if(x < 0)putchar('-'),x = -x;
    if(x > 9)write(x / 10);
    putchar(x % 10 + '0');
}
const int N = 1e6 + 5;
ll pt[N], siz[N], depth[N], fa[N], son[N], top[N], dfn[N], rnk[N], tr[4 * N], lz[4 * N];//往dfn里塞进点,蹦出DFN,往rnk里塞DFN,蹦出点 
ll n, m, from, to, cnt;
vector<int> G[N];
int Tfound(ll u,ll dep){
	son[u] = -1, siz[son[u]] = 0, depth[u] = dep, siz[u] = 1;//重子节点初始化,大小初始化,深度设置 
	for(auto v:G[u]){
		siz[u] += Tfound(v, dep + 1), fa[v] = u;//加上子树,设置父亲 
		if(son[u] == -1||siz[v] > siz[son[u]]) son[u] = v;//调整重子节点 
	}
	return siz[u];
}
void dfs(ll u,ll t){
	top[u] = t, dfn[u] = ++cnt, rnk[cnt] = u;
	if(son[u] == -1) return;//叶子节点没有子节点
	dfs(son[u], t);//优先遍历重子节点,以保证DFN有序
	for(auto v:G[u]) if(v != son[u]) dfs(v, v);//没来过欸,是另一条链 
}
void Build(int s,int t,int p){//对DFN建线段树 
	if(s == t){
		tr[p] = pt[rnk[s]];
		return;
	}
	int m = (s + t) >> 1;
	Build(s, m, p1);
	Build(m + 1, t, p2);
	tr[p] = tr[p1] + tr[p2];
}
void PushDown(int p,int l,int r){
	if(lz[p]){
		int m = (l + r) >> 1;
		tr[p1] += lz[p] * (m - l + 1), tr[p2] += lz[p] * (r - m);
		lz[p1] += lz[p], lz[p2] += lz[p];
		lz[p] = 1145141919810;
		lz[p] = 0; 
	}
}
void RangeAdd(int l, int r,int s,int t,int p,int c){
	if(s>=l && t<=r){
		tr[p] += c * (t - s + 1), lz[p] += c; 
		return;
	}
	PushDown(p, s, t);
	int m = (s + t) >> 1;
	if(r <= m)RangeAdd(l, r, s, m, p1, c);
	if(m < l) RangeAdd(l, r, m + 1, t, p2, c);
	tr[p] = tr[p1] + tr[p2];
}
ll Query(int l,int r,int s,int t,int p){
	if(s >= l && t <= r)return tr[p];
	PushDown(p, s, t);
	int m = (s + t) >> 1;
	ll ret = 0;
	if(l <= m)ret += Query(l, r, s, m, p1);
	if(r > m) ret += Query(l, r, m + 1, t, p2);
	return ret; 
}
ll Q_line(int x,int y){
	ll ret = 0;
	while(top[x] != top[y]){
		if(depth[top[x]] < depth[top[y]])swap(x,y);
		ret += Query(dfn[top[x]], dfn[x], 1, n, 1);
		x = fa[top[x]];
	}
	if(dfn[x] > dfn[y])swap(x, y);
	ret += Query(dfn[x], dfn[y], 1, n, 1);
	return ret;
}
int main(){
	n = read(); m = read();
	for(int i = 1; i <= n; i++) pt[i] = read();//点权 
	for(int i = 1; i < n; i++ ){//加边 
		from = read(); to = read();
		G[from].push_back(to);
	}
	Tfound(1, 1);//一次DFS 
	dfs(1, 1);  //  二次DFS
	Build(1, n, 1);
	while(m--){
		int op, a, c;
		op = read();a = read();
		if(op == 1){
			c = read();
			RangeAdd(dfn[a], dfn[a], 1, n, 1, c);
		} 
		else if(op == 2){
			c = read();
			RangeAdd(dfn[a], dfn[a] + siz[a] - 1, 1, n, 1, c);
		}
		else{
			write(Q_line(a, 1));
			puts("");
		}
	}
}
/* 
BOTTOM = DFN + SIZ - 1
*/

第二版WA0,样例通过 WA0code

#include<bits/stdc++.h>
#define p1 (p << 1)
#define p2 ((p << 1) + 1)
using namespace std;
typedef long long ll;
inline ll read(){
    ll x = 0, f = 1;char ch = getchar();
    while(ch < '0'||ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    return x*f;
}
void write(ll x){
    if(x < 0)putchar('-'),x = -x;
    if(x > 9)write(x / 10);
    putchar(x % 10 + '0');
}
const int N = 1e5 + 5;
ll pt[N], siz[N], depth[N], fa[N], son[N], top[N], dfn[N], rnk[N], tr[4 * N], lz[4 * N];//往dfn里塞进点,蹦出DFN,往rnk里塞DFN,蹦出点 
ll n, m, from, to, cnt;
vector<int> G[N];
int Tfound(ll u,ll dep){
//	printf("u = %d, dep = %d,fa[u] = %d\n",u,dep,fa[u]);
	son[u] = -1, depth[u] = dep, siz[u] = 1;//重子节点初始化,大小初始化,深度设置 
	for(auto v:G[u]){
		if(v == fa[u])continue;
		fa[v] = u, siz[u] += Tfound(v, dep + 1);//加上子树,设置父亲 
		if(son[u] == -1||siz[v] > siz[son[u]]) son[u] = v;//调整重子节点 
	}
	return siz[u];
}
void dfs(ll u,ll t){
	top[u] = t, dfn[u] = ++cnt, rnk[cnt] = u;
	if(son[u] == -1) return;//叶子节点没有子节点
	dfs(son[u], t);//优先遍历重子节点,以保证DFN有序
	for(auto v:G[u]) if(v != son[u] && v != fa[u]) dfs(v, v);//没来过欸,是另一条链 
}
void Build(int s,int t,int p){//对DFN建线段树 
	if(s == t){
		tr[p] = pt[rnk[s]];
		return;
	}
	int m = (s + t) >> 1;
	Build(s, m, p1);
	Build(m + 1, t, p2);
	tr[p] = tr[p1] + tr[p2];
}
void PushDown(int p,int l,int r){
	if(lz[p]){
		int m = (l + r) >> 1;
		tr[p1] += lz[p] * (m - l + 1), tr[p2] += lz[p] * (r - m);
		lz[p1] += lz[p], lz[p2] += lz[p];
		lz[p] = 0; 
	}
}
void RangeAdd(int l, int r,int s,int t,int p,int c){
	if(s >= l && t <= r){
		tr[p] += c * (t - s + 1), lz[p] += c; 
		return;
	}
	PushDown(p, s, t);
	int m = (s + t) >> 1;
	if(r <= m)RangeAdd(l, r, s, m, p1, c);
	if(m < l) RangeAdd(l, r, m + 1, t, p2, c);
	tr[p] = tr[p1] + tr[p2];
}
ll Query(int l,int r,int s,int t,int p){
	if(s >= l && t <= r)return tr[p];
	PushDown(p, s, t);
	int m = (s + t) >> 1;
	ll ret = 0;
	if(l <= m)ret += Query(l, r, s, m, p1);
	if(r > m) ret += Query(l, r, m + 1, t, p2);
	return ret; 
}
ll Q_line(int x,int y){
	ll ret = 0;
	while(top[x] != top[y]){
		if(depth[top[x]] < depth[top[y]])swap(x,y);
		ret += Query(dfn[top[x]], dfn[x], 1, n, 1);
		x = fa[top[x]];
	}
	if(dfn[x] > dfn[y])swap(x, y);
	ret += Query(dfn[x], dfn[y], 1, n, 1);
	return ret;
}
int main(){
	freopen("P3178_1.in","r",stdin);
	freopen("out.out","w",stdout);
	fa[1] = 1;
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i++) scanf("%lld",&pt[i]);//点权 
	for(int i = 1; i < n; i++ ){//加边 
		from = read(); to = read();
		G[from].push_back(to);
		G[to].push_back(from);
	}
	Tfound(1, 1);//一次DFS 
	dfs(1, 1);  //  二次DFS
	Build(1, n, 1);
	while(m--){
		int op, a, c;
		op = read();a = read();
		if(op == 1){
			c = read();
			RangeAdd(dfn[a], dfn[a], 1, n, 1, c);
		} 
		else if(op == 2){
			c = read();
			RangeAdd(dfn[a], dfn[a] + siz[a] - 1, 1, n, 1, c);
		}
		else{
			write(Q_line(a, 1));
			puts("");
		}
	}
}
/* 
BOTTOM = DFN + SIZ - 1
*/

希望可以有神犇调树剖

悬N关

2024/3/19 21:38
加载中...