Codeforces 1621H - Trains and Airplanes

发布时间 2023-07-20 12:10:12作者: tzc_wk

这能 3500?

对于一组在 \(u\) 上的询问,考虑每种线路 \(x\),假设 \(1\to u\) 路径上线路 \(x\) 的长度为 \(len\),那么不难发现收罚款的次数只有两种可能:\(\lfloor\dfrac{len}{T}\rfloor\) 或者 \(\lfloor\dfrac{len}{T}\rfloor+1\),且对于一个 \(v\) 满足 \(z_u=z_v\)\(v\)\(u\) 子树内,并且从 \(v\) 开始走到 \(1\) 交罚款的次数为前者,那么满足 \(dis_v\bmod T\) 属于环上一段区间,而 \(k\) 只有 \(26\),所以本质不同的段最多只有 \(26\) 种,离散化,然后使用线段树合并则可以知道是否存在符合要求的 \(v\) 满足 \(dis_v\bmod T\in[l,r]\),如果存在就更新答案即可。时间复杂度 \(O((n+q)k\log n)\),好像有不带 log 做法,懒得研究了,能过就行(

坑点:\(\lfloor\dfrac{len}{T}\rfloor·fine_c\) 可能会爆 long long。

const int MAXN=2e5;
const int MAXK=26;
const int MAXP=MAXN*80;
const ll INF=1e18;
int n,K,T,qu,nd[MAXK+5],cst[MAXK+5],fa[MAXN+5];
int hd[MAXN+5],to[MAXN*2+5],nxt[MAXN*2+5],val[MAXN*2+5],ec;
void adde(int u,int v,int w){to[++ec]=v;val[ec]=w;nxt[ec]=hd[u];hd[u]=ec;}
char str[MAXN+5];ll dis[MAXN+5],res[MAXN+5];
struct node{int ch[2],val;}s[MAXP+5];
int rt[MAXN+5],ncnt=0;
void modify(int &k,int l,int r,int p,int v){
	if(!k)k=++ncnt;s[k].val+=v;if(l==r)return;
	int mid=l+r>>1;
	if(p<=mid)modify(s[k].ch[0],l,mid,p,v);
	else modify(s[k].ch[1],mid+1,r,p,v);
}
int merge(int x,int y,int l,int r){
	if(!x||!y)return x+y;int mid=l+r>>1,z=++ncnt;
	if(l==r)return s[z].val=s[x].val+s[y].val,z;
	s[z].ch[0]=merge(s[x].ch[0],s[y].ch[0],l,mid);
	s[z].ch[1]=merge(s[x].ch[1],s[y].ch[1],mid+1,r);
	s[z].val=s[x].val+s[y].val;
	return z;
}
int query(int k,int l,int r,int ql,int qr){
	if(!k||ql>qr)return 0;
	if(ql<=l&&r<=qr)return s[k].val;int mid=l+r>>1;
	if(qr<=mid)return query(s[k].ch[0],l,mid,ql,qr);
	else if(ql>mid)return query(s[k].ch[1],mid+1,r,ql,qr);
	else return query(s[k].ch[0],l,mid,ql,mid)+query(s[k].ch[1],mid+1,r,mid+1,qr);
}
void dfs0(int x,int f){
	modify(rt[x],0,T-1,dis[x]%T,1);fa[x]=f;
	for(int e=hd[x];e;e=nxt[e]){
		int y=to[e],w=val[e];if(y==f)continue;
		dis[y]=dis[x]+w;dfs0(y,x);
		if(str[x]==str[y])rt[x]=merge(rt[x],rt[y],0,T-1);
	}
}
vector<tuple<vector<int>,vector<int>,int> >qv[MAXN+5];
vector<int>pt[MAXN+5];
void dfs(int x,int f){
	if(x!=1)pt[str[x]-'A'].pb(x);
	vector<tuple<int,ll,ll> >itvls;
	for(int i=0;i<K;i++)if(!pt[i].empty()&&i!=str[x]-'A')
		itvls.pb(mt(i,dis[fa[pt[i][0]]]+1,dis[pt[i].back()]));
	for(auto t:qv[x]){
		vector<int>N=get<0>(t),C=get<1>(t);int id=get<2>(t);
		ll sum=0;vector<pii>eve;
		for(auto tt:itvls){
			int v=get<0>(tt);ll l=get<1>(tt),r=get<2>(tt);
			ll v0=((r-l+1)/T<=INF/C[v])?min((ll)N[v],1ll*((r-l+1)/T)*C[v]):N[v];
			ll v1=((r-l+1)/T<=INF/C[v])?min((ll)N[v],1ll*((r-l+1)/T+1)*C[v]):N[v];
			sum+=v0;
			if(v0!=v1){
				int _l=l%T,_r=(r+1)%T;
				if(_l==_r)continue;
				if(_l<=_r)eve.pb(mp(_l,v1-v0)),eve.pb(mp(_r,-(v1-v0)));
				else{
					eve.pb(mp(_l,v1-v0)),eve.pb(mp(T,-(v1-v0)));
					eve.pb(mp(0,v1-v0)),eve.pb(mp(_r,-(v1-v0)));
				}
			}
		}
		eve.pb(mp(T,0));eve.pb(mp(0,0));sort(eve.begin(),eve.end());
		ll mn=INF,cur=0;
		for(int i=0;i+1<eve.size();i++){
			cur+=eve[i].se;
//			printf("!!! %d %d %d\n",eve[i].fi,eve[i+1].fi-1,query(rt[x],0,T-1,eve[i].fi,eve[i+1].fi-1));
			if(query(rt[x],0,T-1,eve[i].fi,eve[i+1].fi-1))
				chkmin(mn,cur+sum);
		}
		res[id]=mn;
	}
	for(int e=hd[x];e;e=nxt[e]){
		int y=to[e];if(y==f)continue;
		dfs(y,x);
	}
	if(x!=1)pt[str[x]-'A'].ppb();
}
int main(){
	scanf("%d",&n);
	for(int i=1,u,v,w;i<n;i++)scanf("%d%d%d",&u,&v,&w),adde(u,v,w),adde(v,u,w);
	scanf("%d%s",&K,str+1);
	for(int i=1;i<=K;i++)scanf("%d",&nd[i]);
	for(int i=1;i<=K;i++)scanf("%d",&cst[i]);
	scanf("%d%d",&T,&qu);dfs0(1,0);
	for(int i=1;i<=qu;i++){
		static char buf[5];int opt;scanf("%d",&opt);
		if(opt==1){
			int v;scanf("%s%d",buf+1,&v);
			nd[buf[1]-'A'+1]=v;res[i]=-1;
		}else if(opt==2){
			int v;scanf("%s%d",buf+1,&v);
			cst[buf[1]-'A'+1]=v;res[i]=-1;
		}else{
			vector<int>ND,CST;int u;scanf("%d",&u);
			for(int j=1;j<=K;j++)ND.pb(nd[j]),CST.pb(cst[j]);
			qv[u].pb(mt(ND,CST,i));
		}
	}
	dfs(1,0);
	for(int i=1;i<=qu;i++)if(res[i]!=-1)printf("%lld\n",res[i]);
	return 0;
}