zoukankan      html  css  js  c++  java
  • [bzoj4129] Haruna’s Breakfast

      树上莫队+分块。。

      求mex的时候就上O(1)修改,O(根号n)查询的分块大法。。。

      然后就套树上莫队模版。。我写的是括号序列的姿势。

      莫队时的L和R有两种姿势。。

      一种是莫队时的L和R表示[1,L]和[1,R]。。也就是根到两个查询节点的两条路径。显然lca一定会被消掉,所以计算答案前补回来。

      第二种是莫队时的L和R表示[L,R]。。需要进行一些分类讨论>_<(具体见其他各路题解

      我这种脑子不够用的蒟蒻肯定是写第一种啦。。。虽然并没有太大区别= =

      数据显然是随机构造的。。所以怎么跑都能过= =。一开始块的大小取成了1竟然3s过

      实测树上莫队块的大小取70~100有奇效。。。(这数据强度和糖果公园的比起来简直。。

      (试了半天块的大小233

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int maxn=50233;
      7 const int kuai=99,kuai2=323;
      8 struct ask{
      9     int l,r,t,id;
     10 }q[maxn];int qnum;
     11 struct modi{
     12     int p,v,pre;
     13 }c[maxn];int cnum;
     14 struct zs{
     15     int too,pre;
     16 }e[maxn<<1];int tot,last[maxn];
     17 int sz[maxn],fa[maxn],dep[maxn],bel[maxn],L[maxn],R[maxn];
     18 int pos[maxn<<1],B[maxn<<1],tim;
     19 int cnt[maxn],sm[maxn];
     20 int v[maxn],pre[maxn];
     21 bool u[maxn];
     22 int i,j,k,n,m;
     23 int an[maxn];
     24  
     25 int ra;char rx;
     26 inline int read(){
     27     rx=getchar(),ra=0;
     28     while(rx<'0'||rx>'9')rx=getchar();
     29     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     30 }
     31 void dfs1(int x){
     32     sz[x]=1,dep[x]=dep[fa[x]]+1;
     33     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x])
     34         fa[e[i].too]=x,dfs1(e[i].too),sz[x]+=sz[e[i].too];
     35 }
     36 void dfs2(int x,int chain){
     37     int i,mx=0;
     38     pos[L[x]=++tim]=x,bel[x]=chain;
     39     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&sz[e[i].too]>sz[mx])mx=e[i].too;
     40     if(!mx){pos[R[x]=++tim]=x;return;}
     41     dfs2(mx,chain);
     42     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&e[i].too!=mx)dfs2(e[i].too,e[i].too);
     43     pos[R[x]=++tim]=x;
     44 }
     45 inline int getlca(int a,int b){
     46     while(bel[a]!=bel[b]){
     47         if(dep[bel[a]]<dep[bel[b]])swap(a,b);
     48         a=fa[bel[a]];
     49     }
     50     return dep[a]<dep[b]?a:b;
     51 }
     52  
     53 inline void vis(int x){
     54     if(v[x]<=n)
     55         if(u[x])
     56             if(--cnt[v[x]]==0)sm[v[x]/kuai2]--;
     57             else;
     58         else if(cnt[v[x]]++==0)sm[v[x]/kuai2]++;
     59     u[x]^=1;
     60 }
     61 inline void change(int x,int y){
     62     if(u[x])vis(x),v[x]=y,vis(x);else v[x]=y;
     63 }
     64 inline int query(){
     65     int i=0;
     66     while(sm[i]==kuai2)i++;
     67     for(i*=kuai2;cnt[i];i++);
     68     return i;
     69 }
     70  
     71 bool cmp(ask a,ask b){
     72     return B[a.l]<B[b.l]||(B[a.l]==B[b.l]&&B[a.r]<B[b.r])||(B[a.l]==B[b.l]&&B[a.r]==B[b.r]&&a.t<b.t);
     73 }
     74 inline void insert(int a,int b){
     75     e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;
     76     e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
     77 }
     78 int main(){
     79     n=read(),m=read();
     80     for(i=1;i<=n;i++)v[i]=pre[i]=read();
     81     for(i=1;i<n;i++)j=read(),insert(j,read());
     82     dfs1(1),dfs2(1,1);
     83      
     84     int id;
     85     for(i=1;i<=m;i++){
     86         id=read(),j=read(),k=read();
     87         if(!id)c[++cnum]=(modi){j,k,pre[j]},pre[j]=k;else{
     88             if(L[j]>L[k])swap(j,k);
     89             q[++qnum]=(ask){L[j],L[k],cnum,qnum};
     90         }
     91     }
     92     for(i=1;i<=tim;i++)B[i]=(i+kuai-1)/kuai;
     93     sort(q+1,q+1+qnum,cmp);
     94      
     95     int l=1,r=1,t=0,lca,x,y;
     96     for(i=1;i<=qnum;i++){
     97         while(t<q[i].t)t++,change(c[t].p,c[t].v);
     98         while(t>q[i].t)change(c[t].p,c[t].pre),t--;
     99         while(l>q[i].l)vis(pos[l--]);
    100         while(r>q[i].r)vis(pos[r--]);
    101         while(l<q[i].l)vis(pos[++l]);
    102         while(r<q[i].r)vis(pos[++r]);
    103          
    104         x=pos[l],y=pos[r],lca=getlca(x,y),
    105         vis(lca),
    106          
    107         an[q[i].id]=query(),
    108         vis(lca);
    109     }
    110     for(i=1;i<=qnum;i++)printf("%d
    ",an[i]);
    111     return 0;
    112 }
    View Code
  • 相关阅读:
    Leetcode:42. Trapping Rain Water
    Leetcode: 41. First Missing Positive
    Leetcode: 40. Combination Sum II
    多项式全家桶
    BZOJ 3878 [AHOI&JSOI2014]奇怪的计算器 (线段树)
    BZOJ 2959 长跑 (LCT+并查集)
    BZOJ 3028 食物 (生成函数+数学题)
    luogu P5504 [JSOI2011]柠檬
    hdu 6399 City Development
    luogu P3826 [NOI2017]蔬菜
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5395188.html
Copyright © 2011-2022 走看看