• [hdu6973]Bookshop


    将询问拆成$x$​到$lca$​和$lca$​($lca$​靠近$y$​的儿子)到$y$​​两部分,分别处理(后者以前者的答案为基础)

    两者是类似地,不妨仅考虑前者:用树剖将该询问拆成dfs序上若干个区间,考虑从后往前遍历dfs序(显然即从下到上),若当前位置被覆盖则执行该节点的操作

    进一步的,考虑将一个位置上的操作对覆盖其的位置批量处理,即将问题离线并维护一棵平衡树,仍从后往前遍历dfs序,并支持:

    1.(在区间右端点时)加入一个数

    2.将当前平衡树中大于等于$k$​的数都减去$k$​

    3.(在区间左端点时)删除一个数

    前两个容易处理(删除可以将下标定为询问编号),对于第三个,对权值分类讨论:

    1.权值在$[0,k)$​中的数不需要处理

    2.权值在$[k,2k)$中的数,每一个数至多经历$o(log V)$​次此操作即会变为0(之后显然就不会被操作了),将这些数取出后再暴力操作,复杂度为$o(qlog nlog V)$

    3.权值在$[2k,infty)$中的数,打懒标记即可(第2类需要暴力处理因为要考虑与$[0,k)$中的数的排名)

    总复杂度即$o(nlog ^{2}n)$,可以通过

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 100005
      4 #define pii pair<int,int>
      5 #define mp make_pair
      6 #define fi first
      7 #define se second
      8 #define s(p) f[k].ch[p]
      9 vector<int>v,va[N],vd[N];
     10 vector<pii>v0[N],v1[N];
     11 int E,rt,t,n,q,x,y,head[N],a[N],st[N],fa[N],sz[N],mx[N],dep[N],dfn[N],idfn[N],top[N];
     12 struct Edge{
     13     int nex,to;
     14 }edge[N<<1];
     15 struct Data{
     16     int fa,val,mx,mn,tag,ch[2];
     17 }f[N];
     18 void add_edge(int x,int y){
     19     edge[E].nex=head[x];
     20     edge[E].to=y;
     21     head[x]=E++;
     22 }
     23 void dfs1(int k,int f,int s){
     24     fa[k]=f,sz[k]=1,mx[k]=0,dep[k]=s;
     25     for(int i=head[k];i!=-1;i=edge[i].nex)
     26         if (edge[i].to!=f){
     27             dfs1(edge[i].to,k,s+1);
     28             sz[k]+=sz[edge[i].to];
     29             if (sz[mx[k]]<sz[edge[i].to])mx[k]=edge[i].to;
     30         }
     31 }
     32 void dfs2(int k,int fa,int t){
     33     dfn[k]=++dfn[0],idfn[dfn[0]]=k,top[k]=t;
     34     if (mx[k])dfs2(mx[k],k,t);
     35     for(int i=head[k];i!=-1;i=edge[i].nex)
     36         if ((edge[i].to!=fa)&&(edge[i].to!=mx[k]))dfs2(edge[i].to,k,edge[i].to);
     37 }
     38 int check(int k){
     39     return f[f[k].fa].ch[1]==k;
     40 }
     41 bool cmp(int x,int y){
     42     return (f[x].val<f[y].val)||(f[x].val==f[y].val)&&(x<y);
     43 }
     44 void upd(int k,int x){
     45     f[k].val+=x,f[k].mx+=x,f[k].mn+=x,f[k].tag+=x;
     46 }
     47 void up(int k){
     48     f[k].mx=max(max(f[s(0)].mx,f[s(1)].mx),f[k].val);
     49     f[k].mn=min(min(f[s(0)].mn,f[s(1)].mn),f[k].val);
     50 }
     51 void down(int k){
     52     if (s(0))upd(s(0),f[k].tag);
     53     if (s(1))upd(s(1),f[k].tag);
     54     f[k].tag=0;
     55 }
     56 void rotate(int k){
     57     int F=f[k].fa,G=f[F].fa,p=check(k);
     58     f[k].fa=G;
     59     if (G)f[G].ch[check(F)]=k;
     60     f[s(p^1)].fa=F,f[F].ch[p]=s(p^1);
     61     f[F].fa=k,s(p^1)=F;
     62     up(F),up(k);
     63 }
     64 void clear(int k){
     65     for(int i=k;i;i=f[i].fa)st[++st[0]]=i;
     66     while (st[0])down(st[st[0]--]);
     67 }
     68 void splay(int k,int fa){
     69     clear(k);
     70     for(int i=f[k].fa;i!=fa;i=f[k].fa){
     71         if (f[i].fa!=fa){
     72             if (check(i)==check(k))rotate(i);
     73             else rotate(k);
     74         }
     75         rotate(k);
     76     }
     77     if (!fa)rt=k;
     78 }
     79 void get_val(int k){
     80     if (!k)return;
     81     v.push_back(k);
     82     get_val(s(0));
     83     get_val(s(1));
     84 }
     85 int find_pre(int k,int x){
     86     if (!k)return 0;
     87     down(k);
     88     if (!cmp(k,x))return find_pre(s(0),x);
     89     int ans=find_pre(s(1),x);
     90     if (ans)return ans;
     91     return k;
     92 }
     93 int find_nex(int k,int x){
     94     if (!k)return 0;
     95     down(k);
     96     if (!cmp(x,k))return find_nex(s(1),x);
     97     int ans=find_nex(s(0),x);
     98     if (ans)return ans;
     99     return k;
    100 }
    101 void add(int k){
    102     clear(k);
    103     int l=find_pre(rt,k),r=find_nex(rt,k);
    104     if (!l){
    105         if (!r)rt=k;
    106         else{
    107             splay(r,0);
    108             f[k].fa=rt,f[rt].ch[0]=k;
    109             up(rt);
    110         }
    111     }
    112     else{
    113         splay(l,0);
    114         if (!r){
    115             f[k].fa=rt,f[rt].ch[1]=k;
    116             up(rt);
    117         }
    118         else{
    119             splay(r,rt);
    120             f[k].fa=f[rt].ch[1],f[f[rt].ch[1]].ch[0]=k;
    121             up(f[rt].ch[1]),up(rt);
    122         }
    123     }
    124 }
    125 void dec(int k){
    126     clear(k);
    127     int l=find_pre(rt,k),r=find_nex(rt,k);
    128     if (!l){
    129         if (!r)rt=0;
    130         else{
    131             splay(r,0);
    132             f[rt].ch[0]=0;
    133             up(rt);
    134         }
    135     }
    136     else{
    137         splay(l,0);
    138         if (!r){
    139             f[rt].ch[1]=0;
    140             up(rt);
    141         }
    142         else{
    143             splay(r,rt);
    144             f[f[rt].ch[1]].ch[0]=0;
    145             up(f[rt].ch[1]),up(rt);
    146         }
    147     }
    148     f[k].fa=0;
    149 }
    150 void update_force(int x,int y,int z){
    151     v.clear();
    152     f[0].val=x,f[q+1].val=y;
    153     int l=find_pre(rt,0),r=find_nex(rt,q+1);
    154     if (!l){
    155         if (!r)get_val(rt);
    156         else{
    157             splay(r,0);
    158             get_val(f[rt].ch[0]);
    159             up(rt);
    160         }
    161     }
    162     else{
    163         splay(l,0);
    164         if (!r){
    165             get_val(f[rt].ch[1]);
    166             up(rt);
    167         }
    168         else{
    169             splay(r,rt);
    170             get_val(f[f[rt].ch[1]].ch[0]);
    171             up(f[rt].ch[1]),up(rt);
    172         }
    173     }
    174     for(int i=0;i<v.size();i++){
    175         dec(v[i]);
    176         f[v[i]].val+=z;
    177         add(v[i]);
    178     }
    179 }
    180 void update_tag(int x,int y,int z){
    181     f[0].val=x,f[q+1].val=y;
    182     int l=find_pre(rt,0),r=find_nex(rt,q+1);
    183     if (!l){
    184         if (!r)upd(rt,z);
    185         else{
    186             splay(r,0);
    187             upd(f[rt].ch[0],z);
    188             up(rt);
    189         }
    190     }
    191     else{
    192         splay(l,0);
    193         if (!r){
    194             upd(f[rt].ch[1],z);
    195             up(rt);
    196         }
    197         else{
    198             splay(r,rt);
    199             upd(f[f[rt].ch[1]].ch[0],z);
    200             up(f[rt].ch[1]),up(rt);
    201         }
    202     }
    203 }
    204 int main(){
    205     f[0].mn=0x3f3f3f3f;
    206     scanf("%d",&t);
    207     while (t--){
    208         scanf("%d%d",&n,&q);
    209         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    210         E=dfn[0]=0;
    211         for(int i=1;i<=n;i++)head[i]=-1;
    212         for(int i=1;i<n;i++){
    213             scanf("%d%d",&x,&y);
    214             add_edge(x,y);
    215             add_edge(y,x);
    216         }
    217         dfs1(1,0,0);
    218         dfs2(1,0,1);
    219         for(int i=1;i<=q;i++){
    220             scanf("%d%d%d",&x,&y,&f[i].val);
    221             v0[i].clear(),v1[i].clear();
    222             while (top[x]!=top[y]){
    223                 if (dep[top[x]]>dep[top[y]]){
    224                     v0[i].push_back(mp(dfn[x],dfn[top[x]]));
    225                     x=fa[top[x]];
    226                 }
    227                 else{
    228                     v1[i].push_back(mp(dfn[top[y]],dfn[y]));
    229                     y=fa[top[y]];
    230                 }
    231             }
    232             if (dfn[x]>dfn[y])v0[i].push_back(mp(dfn[x],dfn[y]));
    233             else v1[i].push_back(mp(dfn[x],dfn[y]));
    234         }
    235         for(int i=1;i<=n;i++)va[i].clear(),vd[i].clear();
    236         for(int i=1;i<=q;i++)
    237             for(int j=0;j<v0[i].size();j++){
    238                 va[v0[i][j].fi].push_back(i);
    239                 vd[v0[i][j].se].push_back(i);
    240             }
    241         rt=0;
    242         for(int i=1;i<=q;i++){
    243             f[i].fa=f[i].tag=f[i].ch[0]=f[i].ch[1]=0;
    244             f[i].mx=f[i].mn=f[i].val;
    245         }
    246         for(int i=n;i;i--){
    247             int k=a[idfn[i]];
    248             for(int j=0;j<va[i].size();j++)add(va[i][j]);
    249             update_force(k,(k<<1)-1,-k);
    250             update_tag((k<<1),1e9,-k);
    251             for(int j=0;j<vd[i].size();j++)dec(vd[i][j]);
    252         }
    253         for(int i=1;i<=n;i++)va[i].clear(),vd[i].clear();
    254         for(int i=1;i<=q;i++)
    255             for(int j=0;j<v1[i].size();j++){
    256                 va[v1[i][j].fi].push_back(i);
    257                 vd[v1[i][j].se].push_back(i);
    258             }
    259         rt=0;
    260         for(int i=1;i<=q;i++){
    261             f[i].fa=f[i].tag=f[i].ch[0]=f[i].ch[1]=0;
    262             f[i].mx=f[i].mn=f[i].val;
    263         }
    264         for(int i=1;i<=n;i++){
    265             int k=a[idfn[i]];
    266             for(int j=0;j<va[i].size();j++)add(va[i][j]);
    267             update_force(k,(k<<1)-1,-k);
    268             update_tag((k<<1),1e9,-k);
    269             for(int j=0;j<vd[i].size();j++)dec(vd[i][j]);
    270         }
    271         for(int i=1;i<=q;i++)printf("%d
    ",f[i].val);
    272     }
    273     return 0;
    274 }
    View Code
  • 相关阅读:
    CSS Tab简洁版,切换标签
    浮动在网页右侧的简洁QQ在线客服
    Marquee 最简单图片滚动特效
    浮动的图片广告
    Button控件设置不能点击
    Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead的解决办法
    BroadcastReceiver组件
    发邮件 Async="true"
    ASP.NET GridView,DataList,Repeater日期格式显示
    Json原理和语法
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15086239.html
Copyright © 2020-2023  润新知