zoukankan      html  css  js  c++  java
  • [BZOJ4336][BJOI2015]骑士的旅行(树链剖分+线段树)

    树链剖分,对每个叶子用multiset记录前K大士兵,其余节点通过从儿子归并维护前K大士兵。过于模板。

      1 #include<set>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define ls (x<<1)
      6 #define rs (ls|1)
      7 #define lson ls,L,mid
      8 #define rson rs,mid+1,R
      9 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     10 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
     11 using namespace std;
     12 
     13 const int N=40010;
     14 int n,m,u,v,op,x,y,Q,K,cnt,tim,dfn[N],son[N],sz[N],dep[N],fa[N],top[N],h[N],to[N<<1],nxt[N<<1];
     15 struct P{ int x,k; }p[N];
     16 struct Se{
     17     int tot,a[30];
     18     Se(){ tot=0; memset(a,0,sizeof(a)); }
     19     Se(const Se &b){ tot=b.tot; memcpy(a,b.a,sizeof(a)); }
     20 }T[N<<2];
     21 multiset<int>S[N<<2];
     22 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
     23 
     24 void dfs(int x){
     25     sz[x]=1; dep[x]=dep[fa[x]]+1;
     26     For(i,x) if ((k=to[i])!=fa[x]){
     27         fa[k]=x; dfs(k); sz[x]+=sz[k];
     28         if (sz[k]>sz[son[x]]) son[x]=k;
     29     }
     30 }
     31 
     32 void dfs2(int x,int tp){
     33     dfn[x]=++tim; top[x]=tp;
     34     if (son[x]) dfs2(son[x],tp);
     35     For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k);
     36 }
     37 
     38 Se merge(Se a,Se b){
     39     Se res;
     40     for (int i=1,j=1; i<=a.tot || j<=b.tot; ){
     41         if ((i<=a.tot) && (j>b.tot || b.a[j]<a.a[i])) res.a[++res.tot]=a.a[i++]; else res.a[++res.tot]=b.a[j++];
     42         if (res.tot==K) break;
     43     }
     44     return res;
     45 }
     46 
     47 void mdf(int x,int L,int R,int pos,int k,int op){
     48     if (L==R){
     49         if (!op) S[x].erase(S[x].find(k)); else S[x].insert(k);
     50         T[x].tot=0; multiset<int>::iterator it=S[x].end();
     51         while (1){
     52             if (it==S[x].begin()) break; it--;
     53             T[x].a[++T[x].tot]=*it;
     54             if (T[x].tot==K) break;
     55         }
     56         return;
     57     }
     58     int mid=(L+R)>>1;
     59     if (pos<=mid) mdf(lson,pos,k,op); else mdf(rson,pos,k,op);
     60     T[x]=merge(T[ls],T[rs]);
     61 }
     62 
     63 Se que(int x,int L,int R,int l,int r){
     64     if (L==l && r==R) return T[x];
     65     int mid=(L+R)>>1;
     66     if (r<=mid) return que(lson,l,r);
     67     else if (l>mid) return que(rson,l,r);
     68         else return merge(que(lson,l,mid),que(rson,mid+1,r));
     69 }
     70 
     71 void solve(int x,int y){
     72     Se res;
     73     for (; top[x]!=top[y]; x=fa[top[x]]){
     74         if (dep[top[x]]<dep[top[y]]) swap(x,y);
     75         res=merge(res,que(1,1,n,dfn[top[x]],dfn[x]));
     76     }
     77     if (dep[x]<dep[y]) swap(x,y);
     78     res=merge(res,que(1,1,n,dfn[y],dfn[x]));
     79     if (!res.tot) puts("-1");
     80         else{ rep(i,1,res.tot) printf("%d ",res.a[i]); puts(""); }
     81 }
     82 
     83 int main(){
     84     freopen("bzoj4336.in","r",stdin);
     85     freopen("bzoj4336.out","w",stdout);
     86     scanf("%d",&n);
     87     rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
     88     dfs(1); dfs2(1,1);
     89     scanf("%d",&m);
     90     rep(i,1,m) scanf("%d%d",&p[i].k,&p[i].x);
     91     scanf("%d%d",&Q,&K);
     92     rep(i,1,m) mdf(1,1,n,dfn[p[i].x],p[i].k,1);
     93     while (Q--){
     94         scanf("%d%d%d",&op,&x,&y);
     95         if (op==1) solve(x,y);
     96         if (op==2) mdf(1,1,n,dfn[p[x].x],p[x].k,0),p[x].x=y,mdf(1,1,n,dfn[p[x].x],p[x].k,1);
     97         if (op==3) mdf(1,1,n,dfn[p[x].x],p[x].k,0),p[x].k=y,mdf(1,1,n,dfn[p[x].x],p[x].k,1);
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    Windbg DUMP
    NET媒体文件操作组件TagLib
    NET Framework、.NET Core、Xamarin
    面向切面编程
    微服务
    NET Core
    Yeoman generator
    Service Fabric
    Vue.JS 2.x
    CoreCLR
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9954344.html
Copyright © 2011-2022 走看看