bzoj4867 舌尖上的由乃
  • 板块学术版
  • 楼主Sweetie_Liu
  • 当前回复4
  • 已保存回复4
  • 发布时间2020/6/2 08:37
  • 上次更新2023/11/7 01:17:55
查看原帖
bzoj4867 舌尖上的由乃
165030
Sweetie_Liu楼主2020/6/2 08:37
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#define int long long
using namespace std;
inline int read() {
	register int w=1,x=0,ch=getchar();
	for(; ch<'0'||ch>'9'; ch=getchar())if(ch=='-')w=-1;
	for(; ch>='0'&&ch<='9'; ch=getchar())x=x*10+ch-'0';
	return x*w;
}
const int MAXN = (int)1e6+10;
int n,m,len,lim;
struct Edge {
	int from,to,val,nxt;
	Edge(int from,int to,int val,int nxt) {
		this->from = from;
		this->to = to;
		this->val = val;
		this->nxt = nxt;
	} Edge() {}
} E[MAXN<<1];
int head[MAXN],tot;
inline void Add_Edge(int from,int to,int val) {
	E[++tot] = Edge(from,to,val,head[from]),head[from] = tot;
}
struct ypa {
	int id,val;
	ypa(int id,int val) {
		this->id = id;
		this->val = val;
	} ypa() {
	}
} a[MAXN];
bool cmp(const ypa &a,const ypa &b){
	return a.val < b.val;
}
int stq[MAXN],enq[MAXN],dfn,size[MAXN];
void dfs(int rt,int pre,int w) {
	stq[rt] = ++dfn;
	a[rt].id = dfn;
	a[rt].val = w;
	size[rt] = 1;
	for(register int to,i=head[rt]; i; i=E[i].nxt) {
		to = E[i].to;
		if(to==pre)continue;
		dfs(to,rt,w+E[i].val);
		size[rt] += size[to];
	}
	enq[rt] = dfn;
}
int K,nublock,st[MAXN],en[MAXN],bel[MAXN],tag[MAXN];
void blockinit() {
	nublock = n/K;
	for(int i=1; i<=nublock; i++) {
		st[i] = K*(i-1)+1;
		en[i] = K*i;
		for(int j=1; j<=K; j++) {
			bel[j+K*(i-1)] = i;
		}
	}
	if(nublock*K<n) {
		for(register int i=nublock*K+1; i<=n; i++) {
			bel[i] = nublock + 1;
		}
		st[nublock+1] = nublock*K+1;
		en[nublock+1] = n;
		nublock ++;
	}
}
int ask(int o,int val) {
	register int l = st[o],r = en[o],mid,ans = l-1;
	register int L = l;
	val -= tag[o];
	while(l<=r) {
		mid = l+r >> 1;
		if(a[mid].val<=val) l = mid + 1,ans = mid;
		else r = mid - 1;
	}
	return ans - L + 1;
}
ypa temp[MAXN],b[MAXN],c[MAXN];
int ptb,ptc;
void divide(int o,int l,int r) {
	ptb = 0,ptc = 0;
	for(register int i=st[o]; i<=en[o]; i++) {
		if(l<=a[i].id&&a[i].id<=r)b[++ptb] = a[i];
		else c[++ptc] = a[i];
	}
}
void Add(int val) {
	for(register int i=1; i<=ptb; i++) {
		b[i].val += val;
	}
}
void merge(int o) {
	int i,j = 1,k = 1;
	for(i = st[o]; i<=en[o]&&j<=ptb&&k<=ptc; i++) {
		if(b[j].val<c[k].val)temp[i] = b[j++];
		else temp[i] = c[k++];
	}
	for(; i<=en[o]&&j<=ptb; i++)temp[i] = b[j++];
	for(; i<=en[o]&&k<=ptc; i++)temp[i] = c[k++];
	for(register int i=st[o]; i<=en[o]; i++)a[i] = temp[i];
}
void change(int l,int r,int val) {
	int bol = bel[l],bor = bel[r];
	lim += val;
	if(bol==bor) {
		divide(bol,l,r);
		Add(val);
		merge(bol);
	} else {
		divide(bol,l,r);
		Add(val);
		merge(bol);
		divide(bor,l,r);
		Add(val);
		merge(bor);
		for(register int i=bol+1; i<bor; i++)tag[i] += val;
	}
}
void rebuild(int t,int last,int tagg) {
	for(register int i=1; i<=ptb; i++) {
		a[last+i] = b[i];
	}
	st[nublock + t] = last+1;
	en[nublock + t] = ptb + last;
	tag[nublock + t] = tagg;
}
int query(int l,int r,int kth) {
	int bol = bel[l],bor = bel[r];
	if(bol==bor) {
		divide(bol,l,r);
		rebuild(1,n,tag[bol]);
	} else {
		divide(bol,l,r);
		rebuild(1,n,tag[bol]);
		divide(bor,l,r);
		rebuild(2,en[nublock+1],tag[bor]);
	}
	register int L = -lim, R = lim,ans;
	while(L<=R) {
		int tas,mid = L+R>>1;
		if(bol==bor) {
			tas = ask(nublock+1,mid);
		} else {
			tas = ask(nublock+1,mid)+ask(nublock+2,mid);
		}
		for(register int i=bol+1; i<bor; i++) {
			tas += ask(i,mid);
		}
		if(tas>=kth)R = mid - 1,ans = mid;
		else L = mid + 1;
	}
	return ans;
}
int tt;
signed main() {
	n = read(),m = read(),tt = read();
	for(register int x,val,i=2; i<=n; i++) {
		x = read(),val = read();
		Add_Edge(i,x,val);
		Add_Edge(x,i,val);
		lim += val;
	}
	K = sqrt(n)*log(n)/log(2);
	dfs(1,0,0);
	blockinit();
	for(register int i=1; i<=nublock; i++) {
		sort(a+st[i],a+en[i]+1,cmp);
	}
	for(register int opt,x,val,i=1; i<=m; i++) {
		opt = read(),x = read(),val = read();
		if(opt==1) {
			if(val>size[x]) {
				printf("-1\n");
				continue;
			}
			printf("%lld\n",query(stq[x],enq[x],val));
		} else {
			change(stq[x],enq[x],val);
		}
	}
	return 0;
}
/*
6 5 10
1 2
1 1
3 3
3 1
3 2
*/ 

求捉虫

2020/6/2 08:37
加载中...