接水果

  对于一个盘子<u,v>(dep[u]<dep[v]),会被考虑在某个水果<a,b>中,当且仅当

    ①lca(u,v)==u时

      设w为u的是v的祖先的儿子,则

      1<=a<=in[u]-1,in[v]<=b<=out[b]或out[u]+1<=a<=n,in[v]<=b<=out[v]

    ②lca(u,v)!=u

      in[u]<=a<=out[u],in[v]<=b<=out[v]

  要么插两个点,要么拆两个矩形

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define maxn 40005
  4 #define maxt 32000005
  5 
  6 int cnt,v[maxn<<1],next[maxn<<1],first[maxn];
  7 int ee,dfn,in[maxn],out[maxn],dep[maxn],f[maxn][18],ans[maxn];
  8 int n,m,Q,nd,tree[maxt],ls[maxt],rs[maxt],root[maxn],Hash[maxn],hh,q[maxn],qq;
  9 struct PLA{int a,b,c;}pla[maxn];
 10 struct EVE{
 11     int x,l,r,k,op,id;
 12     EVE(){}
 13     EVE(int _x,int _l,int _r,int _k,int _op,int _id){
 14         x=_x,l=_l,r=_r,k=_k,op=_op,id=_id;
 15     }
 16     bool operator<(const EVE &t)const{
 17         if(x==t.x)return op<t.op;
 18         else return x<t.x;
 19     }
 20 }eve[maxn*5];
 21 int read(){
 22     int tmp=0;char ch=0;
 23     while(!isdigit(ch))ch=getchar();
 24     while(isdigit(ch)){
 25         tmp=tmp*10+ch-'0';
 26         ch=getchar();
 27     }
 28     return tmp;
 29 }
 30 void add(int st,int end){
 31     v[++cnt]=end;
 32     next[cnt]=first[st];
 33     first[st]=cnt;
 34 }
 35 void dfs(int x){
 36     in[x]=++dfn;
 37     for(int e=first[x];e;e=next[e]){
 38         if(v[e]!=f[x][0]){
 39             f[v[e]][0]=x;
 40             dep[v[e]]=dep[x]+1;
 41             dfs(v[e]);
 42         }
 43     }
 44     out[x]=dfn;
 45 }
 46 void eveplus(int a,int b,int c,int d,int val){
 47     if(a>b||c>d)return;
 48     eve[++ee]=EVE(a,c,d,val,0,0);
 49     eve[++ee]=EVE(b,c,d,val,2,0);
 50     eve[++ee]=EVE(c,a,b,val,0,0);
 51     eve[++ee]=EVE(d,a,b,val,2,0);
 52 }
 53 void update_y(int &rt,int l,int r,int pos,int x){
 54     if(!rt)rt=++nd;
 55     if(l==r){
 56         tree[rt]+=x;
 57         return;
 58     }
 59     int mid=(l+r)>>1;
 60     if(pos<=mid)update_y(ls[rt],l,mid,pos,x);
 61     else update_y(rs[rt],mid+1,r,pos,x);
 62     tree[rt]=tree[ls[rt]]+tree[rs[rt]];
 63 }
 64 void update_x(int l,int r,int x,int y){
 65     for(int i=r;i>=1;i-=i&-i)
 66         update_y(root[i],1,hh,x,y);
 67     l--;
 68     for(int i=l;i>=1;i-=i&-i)
 69         update_y(root[i],1,hh,x,-y);
 70 }
 71 int query_y(int l,int r,int k){
 72     if(l==r)return Hash[l];
 73     int mid=(l+r)>>1,tmp=0;
 74     for(int i=1;i<=qq;i++)tmp+=tree[ls[q[i]]];
 75     if(tmp>=k){
 76         for(int i=1;i<=qq;i++)q[i]=ls[q[i]];
 77         return query_y(l,mid,k);
 78     }
 79     else{
 80         for(int i=1;i<=qq;i++)q[i]=rs[q[i]];
 81         return query_y(mid+1,r,k-tmp);
 82     }
 83 }
 84 int query_x(int x,int k){   
 85     qq=0;
 86     for(int i=x;i<=n;i+=i&-i)
 87         q[++qq]=root[i];
 88     return query_y(1,hh,k);
 89 }
 90 int jump(int x,int len){
 91     int i=0;
 92     while(len){
 93         if(len&1)x=f[x][i];
 94         len>>=1;
 95         i++;
 96     }
 97     return x;
 98 }
 99 int main(){
100     int a,b,c;
101     n=read(),m=read(),Q=read();
102     for(int i=1;i<n;i++){
103         a=read(),b=read();
104         add(a,b),add(b,a);
105     }
106     dfs(1);
107     for(int j=1;(1<<j)<n;j++)
108         for(int i=1;i<=n;i++)
109             f[i][j]=f[f[i][j-1]][j-1];
110     for(int i=1;i<=m;i++){
111         pla[i].a=read(),pla[i].b=read(),pla[i].c=read();
112         Hash[++hh]=pla[i].c;
113     }
114     sort(Hash+1,Hash+1+hh);
115     hh=unique(Hash+1,Hash+1+hh)-(Hash+1);
116     for(int i=1;i<=m;i++){
117         pla[i].c=lower_bound(Hash+1,Hash+1+hh,pla[i].c)-Hash;
118         a=pla[i].a,b=pla[i].b;
119         if(dep[a]>dep[b])swap(a,b);
120         if(in[a]<=in[b]&&out[a]>=out[b]){
121             int w=jump(b,dep[b]-dep[a]-1);
122             eveplus(1,in[w]-1,in[b],out[b],pla[i].c);
123             eveplus(out[w]+1,n,in[b],out[b],pla[i].c);
124         }
125         else eveplus(in[a],out[a],in[b],out[b],pla[i].c);
126     }
127     for(int i=1;i<=Q;i++){
128         a=read(),b=read(),c=read();
129         eve[++ee]=EVE(in[a],in[b],in[b],c,1,i);   
130     }
131     sort(eve+1,eve+1+ee);
132     for(int i=1;i<=ee;i++){
133         if(!eve[i].op)update_x(eve[i].l,eve[i].r,eve[i].k,1);
134         if(eve[i].op==1)ans[eve[i].id]=query_x(eve[i].l,eve[i].k);
135         if(eve[i].op==2)update_x(eve[i].l,eve[i].r,eve[i].k,-1);
136     }
137     for(int i=1;i<=Q;i++)
138         printf("%d\n",ans[i]);
139     return 0;
140 }   
View Code

 

posted @ 2016-01-03 18:18  Ngshily  阅读(253)  评论(0编辑  收藏  举报