最开始80,调了114514小时,现在还TLE最后一个点
查看原帖
最开始80,调了114514小时,现在还TLE最后一个点
763782
zbojin楼主2023/9/30 17:49
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1e6 + 5;
const int INF = 0x3f3f3f3f;
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)

//FastIO
using u32=unsigned;
struct IO_Tp{
	const static int _I_Buffer_Size=53<<20; char _I_Buffer[_I_Buffer_Size],*_I_pos=_I_Buffer;
	const static int _O_Buffer_Size=33<<20; char _O_Buffer[_O_Buffer_Size],*_O_pos=_O_Buffer; u32 m[10000];
	IO_Tp(){
		constexpr u32 e0='\0\0\0\1',e1='\0\0\1\0',e2='\0\1\0\0',e3='\1\0\0\0'; int x=0;
		for(u32 i=0,c0='0000';i!=10;++i,c0+=e0)
		for(u32 j=0,c1=c0;j!=10;++j,c1+=e1)
		for(u32 k=0,c2=c1;k!=10;++k,c2+=e2)
		for(u32 l=0,c3=c2;l!=10;++l,c3+=e3) m[x++]=c3;
		fread(_I_Buffer,1, _I_Buffer_Size,stdin);
	}
	~IO_Tp(){fwrite(_O_Buffer,1,_O_pos-_O_Buffer,stdout);}
	IO_Tp &operator>>(int &res){
		bool rev=0;
		while(!isdigit(*_I_pos)&&*_I_pos!='-') ++_I_pos;
		if(*_I_pos=='-') rev=1,++_I_pos; res=*_I_pos++-'0';
		while(isdigit(*_I_pos)) res=res*10+(*_I_pos++ - '0');
		if(rev) res=-res; return *this;
	}
	IO_Tp &operator<<(int x){
		if(x==0){*_O_pos++='0'; return *this;}
		static char _buf[35]; char *_pos=_buf+35;
		while(x>=10000) *--reinterpret_cast<u32*&>(_pos)=m[x%10000],x/=10000;
		*--reinterpret_cast<u32*&>(_pos)=m[x];
		_pos+=(x<1000)+(x<100)+(x<10);
		_O_pos=copy(_pos,_buf+35,_O_pos);
		return *this;
	}
	IO_Tp &operator<<(char ch){*_O_pos++=ch; return *this;}
} IO;
//FastIO

struct Matrix {
	int Map[2][2];
	
	Matrix() {
		memset(Map, 0, sizeof(Map));
	}
	
	int * operator[] (int d) {
		return Map[d];
	}
} tree[MAXN << 2], g[MAXN], ans, last, now;

Matrix operator * (Matrix m1, Matrix m2) {
	Matrix mm;
	mm[0][0] = max(m1[0][0] + m2[0][0], m1[0][1] + m2[1][0]);
	mm[1][0] = max(m1[1][0] + m2[0][0], m1[1][1] + m2[1][0]);
	mm[0][1] = max(m1[0][0] + m2[0][1], m1[0][1] + m2[1][1]);
	mm[1][1] = max(m1[1][0] + m2[0][1], m1[1][1] + m2[1][1]);
	return mm;
}

int f[MAXN][2], lastans;
int n, m, a[MAXN], EdgeCnt, head[MAXN], u, v;

struct Edge {
	int v, pre;
} e[MAXN << 3];

void AddEdge(int u, int v) {
	EdgeCnt++;
	e[EdgeCnt].v = v;
	e[EdgeCnt].pre = head[u];
	head[u] = EdgeCnt;
}

int cnt, fa[MAXN], dep[MAXN], son[MAXN], siz[MAXN], End[MAXN], rnk[MAXN], dfn[MAXN], top[MAXN];

void dfs1(int x);
void dfs2(int x, int t);

void Do(int to, int x) {
	fa[to] = x;
	dep[to] = dep[x] + 1;
	dfs1(to);
	siz[x] += siz[to];
	if(son[x] == -1 || siz[to] > siz[son[x]]) son[x] = to;
	f[x][1] += f[to][0];
	f[x][0] += max(f[to][0], f[to][1]);
}

void dfs1(int x) {
	son[x] = -1;
	siz[x] = 1;
	f[x][1] = a[x];
	for(int i = head[x]; i; i = e[i].pre) {
		int to = e[i].v;
		if(!dep[to]) Do(to, x);
	}
}

void Do2(int to, int x) {
	dfs2(to, to);
	g[x][0][0] += max(f[to][0], f[to][1]);
	g[x][1][0] += f[to][0];
}

void dfs2(int x, int t) {
	top[x] = t;
	dfn[x] = ++cnt;
	rnk[cnt] = x;
	End[t] = cnt;
	g[x][1][0] = a[x];
	g[x][1][1] = -INF;
	if(son[x] == -1) return;
	dfs2(son[x], t);
	for(int i = head[x]; i; i = e[i].pre) {
		int to = e[i].v;
		if(to != fa[x] && to != son[x]) Do2(to, x);
	}
	g[x][0][1] = g[x][0][0];
}

void push_up(int p) {
	tree[p] = tree[ls(p)] * tree[rs(p)];
}

void build(int p, int l, int r) {
	if(l == r) {
		tree[p] = g[rnk[l]];
		return;
	}
	int mid = (l + r) >> 1;
	build(ls(p), l, mid);
	build(rs(p), mid + 1, r);
	push_up(p);
}

Matrix query(int p, int nl, int nr, int l, int r) {
	if(nl <= l && r <= nr) return tree[p];
	int mid = (l + r) >> 1;
	if(nr <= mid) return query(ls(p), nl, nr, l, mid);
	if(mid < nl) return query(rs(p), nl, nr, mid + 1, r);
	return query(ls(p), nl, nr, l, mid) * query(rs(p), nl, nr, mid + 1, r);
}

void modify(int p, int l, int r, int pos) {
	if(l == r) {
		tree[p] = g[rnk[l]];
		return;
	}
	int mid = (l + r) >> 1;
	if(pos <= mid) modify(ls(p), l, mid, pos);
	else modify(rs(p), mid + 1, r, pos);
	push_up(p);
}

void update(int x, int val) {
	g[x][1][0] += val - a[x];
	a[x] = val;
	while(x) {
		last = query(1, dfn[top[x]], End[top[x]], 1, n);
		modify(1, 1, n, dfn[x]);
		now = query(1, dfn[top[x]], End[top[x]], 1, n);
		x = fa[top[x]];
		g[x][0][0] += max(now[0][0], now[1][0]) - max(last[0][0], last[1][0]);
		g[x][0][1] = g[x][0][0];
		g[x][1][0] += now[0][0] - last[0][0];
	}
}

int main() {
	IO >> n >> m;
	for(int i = 1; i <= n; ++i) IO >> a[i];
	for(int i = 1; i < n; ++i) {
		IO >> u >> v;
		AddEdge(u, v);
		AddEdge(v, u);
	}
	dep[1] = 1;
	dfs1(1); dfs2(1, 1);
	build(1, 1, n);
	while(m--) {
		IO >> u >> v;
		u ^= lastans;
		update(u, v);
		ans = query(1, 1, End[1], 1, n);
		lastans = max(ans[0][0], ans[1][0]);
		IO << lastans << '\n';
	}
	return 0;
}

请问如何继续优化?

2023/9/30 17:49
加载中...