QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#601686#9373. Query on TreefutarianWA 52ms108256kbC++148.2kb2024-09-30 10:51:312024-09-30 10:51:32

Judging History

你现在查看的是最新测评结果

  • [2024-09-30 10:51:32]
  • 评测
  • 测评结果:WA
  • 用时:52ms
  • 内存:108256kb
  • [2024-09-30 10:51:31]
  • 提交

answer

//母亲?懂? 
#include "bits/stdc++.h"
using namespace std;
#define int long long
const int Len = 3e5 + 15;
const int Inf = 1e15;
int mxdep,dep[Len],xxdep[Len],N,n,q,id,siz[Len],nfd[Len],nfb[Len],dfn[Len],bfn[Len],fa[20][Len],a[Len],b[Len],t[Len],head[Len],cnt,L[20][Len],R[20][Len];
struct node
{
	int nxt,to;
}edge[Len << 1];
inline void Addd(int from,int to)
{
	edge[++ cnt].to = to;
	edge[cnt].nxt = head[from];
	head[from] = cnt;
}
inline int read()
{
	char ch = getchar();
	int x = 0 , f = 1;
	while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}
	while('0' <= ch && ch <= '9')
	{
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar();
	}
	return x * f;
}
void write(int x)
{
	if(x < 0){putchar('-');x = -x;}
	if(x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
inline void writeN(int x){write(x) , putchar('\n');}
void dfs(int x,int f)
{
	siz[x] = 1;
	if(x == 1) dep[x] = 11;
	else dep[x] = dep[f] + 1;
	xxdep[x] = dep[x];
	dfn[x] = ++ id;nfd[id] = x;
	mxdep = max(mxdep , dep[x]);
	fa[0][x] = x;L[0][x] = R[0][x] = bfn[x];
	if(x == 1)
	{
		int now = 0;
		for(int i = 1 ; i <= 10 ; i ++) 
		{
			now = fa[i][x] = n + i;
			//printf("%d %d %d\n",i,x,fa[i][x]);
			L[i][now] = R[i][now] = 1;
		}
	}
	else
	{
		int now = 0;
		for(int i = 1 ; i <= 10 ; i ++) 
		{
			now = fa[i][x] = fa[i - 1][f];
			//printf("%d %d %d\n",i,x,fa[i][x]);
			L[i][now] = min(L[i][now] , bfn[x]) ,  R[i][now] = max(R[i][now] , bfn[x]);
		}
	}
	for(int e = head[x] ; e ; e = edge[e].nxt)
	{
		int to = edge[e].to;
		if(to == f) continue;
		dfs(to , x);
		siz[x] += siz[to];
		xxdep[x] = max(xxdep[x] , xxdep[to]);
	}
}
void bfs()
{
	queue<int> Q;
	Q.push(1);
	while(!Q.empty())
	{
		int p = Q.front();Q.pop();
		bfn[p] = ++ id;nfb[p] = id;
		for(int e = head[p] ; e ; e = edge[e].nxt)
		{
			int to = edge[e].to;
			if(!bfn[to]) Q.push(to);
		}
	}
}
//Sub 1:树状数组维护路径和,区间加,单点查 
int treec[Len];
#define lowbit(x) (x & (-x))
inline void Add(int x,int d)
{
	while(x <= n)
	{
		treec[x] += d;
		x += lowbit(x);
	}
}
inline void Upd(int l,int r,int w){Add(l , w) , Add(r + 1 , -w);}
inline int qry(int x)
{
	int res = 0;
	while(x)
	{
		res += treec[x];
		x -= lowbit(x);
	}
	return res;
}
//Sub 2:线段树维护 bfs 序上的 max A,操作:区间加区间 max
//Sub3:线段树维护 dfs 序上的 b_o + t_o + roadsum,涉及区间加区间 max 单点改
struct Seg
{
	#define ls(x) (x << 1)
	#define rs(x) (x << 1 | 1)
	int mx[Len << 2],tag[Len << 2];
	inline void push_up(int p){mx[p] = max(mx[ls(p)] , mx[rs(p)]);}
	inline void push_down(int p)
	{
		if(tag[p])
		{
			tag[ls(p)] += tag[p] , tag[rs(p)] += tag[p];
			mx[ls(p)] += tag[p] , mx[rs(p)] += tag[p];
			tag[p] = 0;
		}
	}
	void build(int p,int l,int r)
	{
		tag[p] = 0;
		if(l == r){mx[p] = a[nfb[l]];return;}
		int mid = (l + r) >> 1;
		build(ls(p) , l , mid) , build(rs(p) , mid + 1 , r);
		push_up(p);
	}
	void Build(int p,int l,int r)
	{
		tag[p] = 0;
		if(l == r){mx[p] = b[nfd[l]];return;}
		int mid = (l + r) >> 1;
		Build(ls(p) , l , mid) , Build(rs(p) , mid + 1 , r);
		push_up(p);
	}
	void updP(int p,int l,int r,int idx,int w)
	{
		if(l == r){mx[p] = w;return;}
		push_down(p);
		int mid = (l + r) >> 1;
		if(idx <= mid) updP(ls(p) , l , mid , idx , w);
		else updP(rs(p) , mid + 1 , r , idx , w);
		push_up(p);
	}
	void update(int p,int l,int r,int nl,int nr,int w)
	{
		if(!nl || !nr || nl > nr) return;
		if(nl <= l && nr >= r) 
		{
			mx[p] += w;
			tag[p] += w;
			return;
		}
		push_down(p);
		int mid = (l + r) >> 1;
		if(nl <= mid) update(ls(p) , l , mid , nl , nr , w);
		if(nr > mid) update(rs(p) , mid + 1 , r , nl , nr , w);
		push_up(p);
	}
	int query(int p,int l,int r,int nl,int nr)
	{
		if(!nl || !nr || nl > nr) return -Inf;
		if(nl <= l && nr >= r) return mx[p];
		push_down(p);
		int mid = (l + r) >> 1 , res = -Inf;
		if(nl <= mid) res = max(res , query(ls(p) , l , mid , nl , nr));
		if(nr > mid) res = max(res , query(rs(p) , mid + 1 , r , nl , nr));
		return res;
	}
}S2,S3;
struct Sec
{
	int l,r;
	Sec(){l = r = 0;}
	Sec(int L,int R){l = L , r = R;}
}rnm[Len];int rtf[Len];
signed main()
{
	int T = read();
	while(T --)
	{
		N = n = read() , q = read();
		for(int i = 1 ; i <= n ; i ++) a[i] = read();
		for(int i = 1 ; i < n ; i ++)
		{
			int x = read() , y = read();
			Addd(x , y) , Addd(y , x);
		}
		for(int i = n + 2 ; i <= n + 10 ; i ++) Addd(i , i - 1);
		Addd(n + 1 , 1);
		N = n + 10;
		for(int i = n + 1 ; i <= n + 9 ; i ++) fa[1][i] = i + 1;
		for(int i = 1 ; i <= N ; i ++) for(int j = 0 ; j <= 10 ; j ++) L[j][i] = n + 1 , R[j][i] = 0;
		bfs();id = 0;
		dfs(1 , 0);//puts("#bfs");for(int i = 1 ; i <= n ; i ++) printf("%d ",bfn[i]);puts("");
		S2.build(1 , 1 , n);
		for(int i = 1 ; i <= n ; i ++)
		{
			t[i] = 0;
			if(L[10][i] > R[10][i]) b[i] = -Inf;
			else b[i] = S2.query(1 , 1 , n , L[10][i] , R[10][i]);
		}
		S3.Build(1 , 1 , n);
		for(int i = 1 ; i <= q ; i ++)
		{
			int o = read(),x = read(),k,v;
			if(o == 1 || o == 2) k = read();
			v = read();
			if(o == 1)
			{
				if(k > xxdep[x] - dep[x] && k >= dep[x])
				{
					puts("GG");
					continue;
				}
				int ff = fa[10 - k][x] , now = x , res = -Inf;
				S2.update(1 , 1 , n , L[k][now] , R[k][now] , v);res = max(res , S2.query(1 , 1 , n , L[k][now] , R[k][now]) + qry(dfn[fa[1][ff]]));
				b[ff] = S2.query(1 , 1 , n , L[10][ff] , R[10][ff]);
				S3.updP(1 , 1 , n , dfn[ff] , b[ff] + qry(dfn[fa[1][ff]]));
				k --;
				now = fa[1][now] , ff = fa[1][ff];
				while(k >= 1 && now <= n)
				{
					S2.update(1 , 1 , n , L[k][now] , L[k - 1][x] - 1 , v);res = max(res , S2.query(1 , 1 , n , L[k][now] , L[k - 1][x] - 1) + qry(dfn[fa[1][ff]]));
					S2.update(1 , 1 , n , R[k - 1][x] + 1 , R[k][now] , v);res = max(res , S2.query(1 , 1 , n , R[k - 1][x] + 1 , R[k][now]) + qry(dfn[fa[1][ff]]));
					b[ff] = S2.query(1 , 1 , n , L[10][ff] , R[10][ff]);
					S3.updP(1 , 1 , n , dfn[ff] , b[ff] + qry(dfn[fa[1][ff]]));
					k --;
					now = fa[1][now] , ff = fa[1][ff];
				}
				if(!k && now <= n) 
				{
					S2.update(1 , 1 , n , L[k][now] , R[k][now] , v);res = max(res , S2.query(1 , 1 , n , L[k][now] , R[k][now]) + qry(dfn[fa[1][ff]]));
					b[ff] = S2.query(1 , 1 , n , L[10][ff] , R[10][ff]);
					S3.updP(1 , 1 , n , dfn[ff] , b[ff] + qry(dfn[fa[1][ff]]));
				}
				writeN(res);
			}
			else if(o == 2)
			{
				int res = -Inf , mxdp = dep[x] + k  , mndp = dep[x] - k , tf = fa[10 - k][x];
				//puts("orznb");
				for(int j = mxdp ; j >= mndp ; j --) 
				{
					rnm[j].l = n + 1 , rnm[j].r = 0;
					rtf[j] = tf;
					tf = fa[1][tf];
				}
				//puts("#1"); 
				int K = k , now = x , nb = 0;
				while(K >= 0 && now <= n)
				{
					for(int j = 0 ; j <= K ; j ++) 
					{
						nb = dep[now] + j;
						rnm[nb].l = min(rnm[nb].l , L[j][now]) , rnm[nb].r = max(rnm[nb].r , R[j][now]);
					}
					K --;
					now = fa[1][now];
				}
				//puts("#2");
				for(int j = mndp ; j <= mxdp ; j ++) 
				{
					
					S2.update(1 , 1 , n , rnm[j].l , rnm[j].r , v);
					b[rtf[j]] = S2.query(1 , 1 , n , L[10][rtf[j]] , R[10][rtf[j]]);
					//printf("%lld %lld %lld %lld %lld %lld\n",j,rnm[j].l,rnm[j].r,rtf[j],L[10][rtf[j]] , R[10][rtf[j]]);
					S3.updP(1 , 1 , n , dfn[rtf[j]] , b[rtf[j]] + qry(dfn[fa[1][rtf[j]]]));
					res = max(res , S2.query(1 , 1 , n , rnm[j].l , rnm[j].r) + qry(dfn[fa[1][rtf[j]]]));
				}
				//puts("#3");
				writeN(res);
			}
			else if(o == 3)
			{
				int K = 9 , res = -Inf;
				for(k = 0 ; k <= K ; k ++) 
				{
					int ff = fa[10 - k][x];
					S2.update(1 , 1 , n , L[k][x] , R[k][x] , v);
					b[ff] = S2.query(1 , 1 , n , L[10][ff] , R[10][ff]);
					S3.updP(1 , 1 , n , dfn[ff] , b[ff] + qry(dfn[fa[1][ff]]));
					res = max(res , S2.query(1 , 1 , n , L[k][x] , R[k][x]) + qry(dfn[fa[1][ff]]));
				}
				Upd(dfn[x] , dfn[x] + siz[x] - 1 , v);
				S3.update(1 , 1 , n , dfn[x] , dfn[x] + siz[x] - 1 , v);
				res = max(res , S3.query(1 , 1 , n , dfn[x] , dfn[x] + siz[x] - 1));
				writeN(res);
			}
		}
		mxdep = cnt = id = 0;
		for(int i = 1 ; i <= N ; i ++) xxdep[i] = nfd[i] = nfb[i] = dfn[i] = bfn[i] = head[i] = 0;
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 108256kb

input:

1
5 5
1 2 1 3 2
1 2
2 3
2 4
4 5
2 2 1 0
1 2 1 3
3 4 -5
2 5 2 3
3 2 -1

output:

3
6
1
5
4

result:

ok 5 lines

Test #2:

score: -100
Wrong Answer
time: 52ms
memory: 108068kb

input:

10000
3 9
42973045452542 34994498886390 -91733395797555
1 3
1 2
1 1 5 -71952967
3 1 -816873082
1 1 5 -842437577
2 3 7 254550528
3 3 -854082700
2 3 2 699808309
3 3 554885567
1 2 7 595565507
1 3 0 -318374053
3 2
-63158159333100 77264362049163 -99188430131116
1 2
3 2
2 2 4 -305866230
3 1 -549738403
3 5...

output:

-1000000000000000
42972228579460
-1000000000000000
42972483129988
-91734812202809
42973182938297
-91733557508933
-1000000000000000
-91733875882986
77264056182933
77263506444530
7065382376488
7065749360235
7066534912965
-85115611272570
-85114714781312
96492412785032
-20428913156111
-20428197540063
96...

result:

wrong answer 1st lines differ - expected: 'GG', found: '-1000000000000000'