记录编号 |
446053 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HNOI 2015]接水果 |
最终得分 |
100 |
用户昵称 |
test |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
1.138 s |
提交时间 |
2017-09-07 15:26:24 |
内存使用 |
8.86 MiB |
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <complex>
#include <stack>
#define LL long long int
#define dob double
using namespace std;
const int N = 40010;
struct Node{int to,next;}E[N<<1];
struct Plate{
int xl,xr,yl,yr,val;
bool operator <(const Plate &p)const{
return val<p.val;
}
}plate[N];
struct Fruit{
int x,y,k,id;
bool operator <(const Fruit &f)const{
return x<f.x;
}
}fruit[N],que1[N],que2[N];
struct Data{
int x,l,r,val;
bool operator <(const Data &l)const{
return x<l.x;
}
}Line[N<<1];
int n,P,Q,Ans[N],cnt,head[N],tot;
int fa[17][N],dep[N],size[N],son[N],top[N],dfn[N],tim,last[N];
struct Bit{
int A[N],vis[N];
inline int lb(int x){
return x&-x;
}
inline void upd(int x,int val){
for(;x<=n;x+=lb(x)){
if(vis[x]!=tim)A[x]=0,vis[x]=tim;
A[x]+=val;
}
}
inline void update(int l,int r,int val){
upd(l,val);upd(r+1,-val);
}
inline int query(int x,int ans=0){
for(;x;x-=lb(x)){
if(vis[x]!=tim)A[x]=0,vis[x]=tim;
ans+=A[x];
}
return ans;
}
}T;
inline int gi(){
int x=0,res=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*res;
}
inline void link(int u,int v){
E[++tot]=(Node){v,head[u]};
head[u]=tot;
}
inline void join(int x){
for(int i=1;i<=16;++i)
fa[i][x]=fa[i-1][fa[i-1][x]];
}
inline void dfs1(int x,int fat){
fa[0][x]=fat;dep[x]=dep[fat]+1;size[x]=1;join(x);
for(int e=head[x];e;e=E[e].next){
int y=E[e].to;if(y==fa[0][x])continue;
dfs1(y,x);size[x]+=size[y];
if(size[son[x]]<size[y])son[x]=y;
}
}
inline void dfs2(int x,int tp){
top[x]=tp;dfn[x]=++tim;
if(son[x])dfs2(son[x],tp);
for(int e=head[x];e;e=E[e].next){
int y=E[e].to;
if(y==fa[0][x] || y==son[x])continue;
dfs2(y,y);
}
last[x]=tim;
}
inline int lca(int x,int y){
while(top[x] != top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[0][top[x]];
}
return dep[x]<dep[y]?x:y;
}
inline int jump(int x,int goal){
//printf("jump %d %d\n",x,goal);
for(int i=16;i>=0;--i)
if(dep[fa[i][x]]>dep[goal])
x=fa[i][x];
return x;
}
/*
把答案(盘子)二分。
把左边的矩形加进去。
然后check,calc一下盘子个数。
递归处理。
*/
inline void solve(int optl,int optr,int l,int r){
if(optl>optr || l>r)return;++tim;
if(optl==optr){
for(int i=l;i<=r;++i)
Ans[fruit[i].id]=plate[optl].val;
return;
}
int mid=(optl+optr)>>1,tot1=0,tot2=0,k=l,tmp=0,cnt1=1,cnt2=l;
for(int i=optl;i<=mid;++i){
Line[++tmp]=(Data){plate[i].xl,plate[i].yl,plate[i].yr,1};
Line[++tmp]=(Data){plate[i].xr+1,plate[i].yl,plate[i].yr,-1};
}
sort(Line+1,Line+tmp+1);sort(fruit+l,fruit+r+1);
while(cnt1<=tmp && cnt2<=r){
if(Line[cnt1].x<=fruit[cnt2].x){
int xl=Line[cnt1].l,xr=Line[cnt1].r,val=Line[cnt1].val;
T.update(xl,xr,val);cnt1++;
}
else{
int sum=T.query(fruit[cnt2].y);
if(sum>=fruit[cnt2].k)que1[++tot1]=fruit[cnt2++];
else fruit[cnt2].k-=sum,que2[++tot2]=fruit[cnt2++];
}
}
while(cnt2<=r){
int sum=T.query(fruit[cnt2].y);
if(sum>=fruit[cnt2].k)que1[++tot1]=fruit[cnt2++];
else fruit[cnt2].k-=sum,que2[++tot2]=fruit[cnt2++];
}
for(int i=1;i<=tot1;++i)fruit[k++]=que1[i];
for(int i=1;i<=tot2;++i)fruit[k++]=que2[i];
solve(optl,mid,l,l+tot1-1);
solve(mid+1,optr,l+tot1,r);
}
int main()
{
freopen("fruit_hnoi2015.in","r",stdin);
freopen("fruit_hnoi2015.out","w",stdout);
n=gi();P=gi();Q=gi();
for(int i=1;i<n;++i){
int u=gi(),v=gi();
link(u,v);link(v,u);
}
dfs1(1,1);dfs2(1,1);
for(int i=1;i<=P;++i){
int a=gi(),b=gi(),c=gi(),u=lca(a,b);
if(dfn[a]>dfn[b])swap(a,b);
if(u^a)plate[++cnt]=(Plate){dfn[a],last[a],dfn[b],last[b],c};
else{
int v=jump(b,a);
if(dfn[v]>1)plate[++cnt]=(Plate){1,dfn[v]-1,dfn[b],last[b],c};
if(last[v]<n)plate[++cnt]=(Plate){dfn[b],last[b],last[v]+1,n,c};
}
}
sort(plate+1,plate+cnt+1);
for(int i=1;i<=Q;++i){
int a=gi(),b=gi(),k=gi();
if(dfn[a]>dfn[b])swap(a,b);
fruit[i]=(Fruit){dfn[a],dfn[b],k,i};
}
sort(fruit+1,fruit+Q+1);
solve(1,cnt,1,Q);
for(int i=1;i<=Q;++i)
printf("%d\n",Ans[i]);
/*fclose(stdin);
fclose(stdout);*/
return 0;
}