zoukankan      html  css  js  c++  java
  • Count on a tree II SPOJ

    https://cn.vjudge.net/problem/SPOJ-COT2

    这个是树上莫队模版啊。。

    树上莫队有两种,第一种就是括号序莫队

    设节点i在括号序中首次出现位置为pl[i]

    那么路径(i,j)上的节点,相当于括号序中pl[i]到pl[j]中所有只出现1次的节点,可能还要加上i,j,lca(i,j)

    更精确的描述:https://blog.csdn.net/xianhaoming/article/details/52201761

    这样很容易用序列莫队+lca(i,j),i,j的特判解决

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<map>
      6 using namespace std;
      7 #define fi first
      8 #define se second
      9 #define mp make_pair
     10 #define pb push_back
     11 typedef long long ll;
     12 typedef unsigned long long ull;
     13 typedef pair<int,int> pi;
     14 int n,m;
     15 int a[40100];
     16 vector<int> e[40100];
     17 struct Q
     18 {
     19     int x,y,n;
     20 }q[100100];
     21 int sz=225;
     22 int d[80100],pl[40100],bl[80100];
     23 bool vis[40100];
     24 int ans[100100],num[40100],an;
     25 int t1[40100];
     26 int anc[40100][20],dep[40100],l2n=19;
     27 map<int,int> ma;
     28 void dfs(int u,int fa)
     29 {
     30     int i;
     31     d[++d[0]]=u;pl[u]=d[0];
     32     anc[u][0]=fa;
     33     dep[u]=dep[fa]+1;
     34     for(i=1;i<=l2n;i++)
     35         anc[u][i]=anc[anc[u][i-1]][i-1];
     36     for(i=0;i<e[u].size();i++)
     37         if(e[u][i]!=fa)
     38             dfs(e[u][i],u);
     39     d[++d[0]]=u;
     40 }
     41 int lca(int x,int y)
     42 {
     43     int t,i;
     44     if(dep[x]<dep[y]){t=x;x=y;y=t;}
     45     for(t=dep[x]-dep[y],i=0;t>0;t>>=1,i++)
     46         if(t&1)    x=anc[x][i];
     47     if(x==y)    return x;
     48     for(i=l2n;i>=0;i--)
     49         if(anc[x][i]!=anc[y][i])
     50         {
     51             x=anc[x][i];
     52             y=anc[y][i];
     53         }
     54     return anc[x][0];
     55 }
     56 bool operator<(const Q &a,const Q &b)
     57 {
     58     return bl[a.x]==bl[b.x]?a.y<b.y:a.x<b.x;
     59 }
     60 void change(int u)
     61 {
     62     if(vis[u])
     63     {
     64         num[a[u]]--;
     65         if(num[a[u]]==0)    an--;
     66         vis[u]=0;
     67     }
     68     else
     69     {
     70         if(num[a[u]]==0)    an++;
     71         num[a[u]]++;
     72         vis[u]=1;
     73     }
     74 }
     75 int main()
     76 {
     77     int i,u,v;
     78     scanf("%d%d",&n,&m);
     79     for(i=1;i<=n;i++)    scanf("%d",&a[i]),t1[++t1[0]]=a[i];
     80     sort(t1+1,t1+t1[0]+1);t1[0]=unique(t1+1,t1+t1[0]+1)-t1-1;
     81     for(i=1;i<=t1[0];i++)    ma[t1[i]]=i;
     82     for(i=1;i<=n;i++)    a[i]=ma[a[i]];
     83     
     84     //for(i=1;i<=n;i++)    printf("a%d %d
    ",i,a[i]);
     85     for(i=1;i<n;i++)
     86     {
     87         scanf("%d%d",&u,&v);
     88         e[u].pb(v);e[v].pb(u);
     89     }
     90     dfs(1,0);
     91     for(i=1;i<=m;i++)
     92     {
     93         scanf("%d%d",&q[i].x,&q[i].y);
     94         q[i].x=pl[q[i].x];q[i].y=pl[q[i].y];
     95         if(q[i].x>q[i].y)    swap(q[i].x,q[i].y);
     96         q[i].n=i;
     97     }
     98     //putchar('a');
     99     //for(i=1;i<=d[0];i++)    printf("%d ",d[i]);
    100     //puts("");
    101     for(i=1;i<=d[0];i++)    bl[i]=(i-1)/sz;
    102     sort(q+1,q+m+1);
    103     int l=1,r=0;
    104     for(i=1;i<=m;i++)
    105     {
    106         while(l>q[i].x)    change(d[--l]);
    107         while(r<q[i].y)    change(d[++r]);
    108         while(l<q[i].x)    change(d[l++]);
    109         while(r>q[i].y)    change(d[r--]);
    110         bool fl1=vis[d[q[i].x]],fl2=vis[d[q[i].y]];
    111         int ll=lca(d[q[i].x],d[q[i].y]);
    112         bool fl3=vis[ll];
    113         //printf("b%d %d %d %d %d %d
    ",q[i].x,q[i].y,ll,fl1,fl2,fl3);
    114         if(!fl1)    change(d[q[i].x]);
    115         if(!fl2)    change(d[q[i].y]);
    116         if(!fl3)    change(ll);
    117         ans[q[i].n]=an;
    118         if(!fl1)    change(d[q[i].x]);
    119         if(!fl2)    change(d[q[i].y]);
    120         if(!fl3)    change(ll);
    121     }
    122     for(i=1;i<=m;i++)    printf("%d
    ",ans[i]);
    123     return 0;
    124 }

    还有一种是树分块后直接做莫队

    树分块的方法很多,按我自己的理解,此时可行的分块方法要求块内部任意两点间距离不超过根号级别,且各个块按照“块树”的dfs序排列(由这个顺序得到块编号)(不确定)

    这样子的话,将所有询问以左端点的块编号为第一关键字,右端点的块编号为第二关键字,排序所有询问,

    每一次转移的时候,两个端点都变了,但是可以当成一个端点一个端点的变;从(u,v1)的答案变到(u,v2)的答案,就是除了以u为根时lca(v1,v2)以外,对(v1,v2)的路径上所有点的“是否在当前答案中”属性取反(划掉的东西我不会证也不想维护)

    根据一些证明,只要首先丢掉每个询问的两个端点的lca(处理这个询问时临时加上就行了),那么从(u,v1)变到(u,v2),只要对(v1,v2)路径上所有点(除了lca)的“是否在当前答案中”属性取反就行了

    证明:https://www.cnblogs.com/RabbitHu/p/MoDuiTutorial.html

    树分块方法:

    (对于方法:如果某个节点父亲所在的块加上自己所在的块大小没超过K(指定的最大块大小),那么将这两个块合并(一般K就取sqrt(n))

    能保证块大小,不能保证块数。。。

    听说菊花图能卡掉。。。然而想了很久,也没想出来什么样的菊花图能卡掉这个方法的树上莫队

    算了,还是不用了)

    1.王室联邦分块

    https://www.lydsy.com/JudgeOnline/problem.php?id=1086

    做法:https://www.cnblogs.com/shenben/p/6368457.html

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 #define fi first
     7 #define se second
     8 #define mp make_pair
     9 #define pb push_back
    10 typedef long long ll;
    11 typedef unsigned long long ull;
    12 typedef pair<int,int> pii;
    13 int n,sz;
    14 vector<int> e[100100];
    15 int st[100100],tp,rt[100100],cnt,bl[100100];
    16 void dfs(int u,int fa)
    17 {
    18     int i,ltp=tp;
    19     for(i=0;i<e[u].size();i++)
    20         if(e[u][i]!=fa)
    21         {
    22             dfs(e[u][i],u);
    23             if(tp-ltp>=sz)
    24             {
    25                 rt[++cnt]=u;
    26                 while(tp!=ltp)    bl[st[tp--]]=cnt;
    27             }
    28         }
    29     st[++tp]=u;
    30 }
    31 int main()
    32 {
    33     int i,a,b;
    34     scanf("%d%d",&n,&sz);
    35     for(i=1;i<n;i++)
    36     {
    37         scanf("%d%d",&a,&b);
    38         e[a].pb(b);e[b].pb(a);
    39     }
    40     dfs(1,0);
    41     while(tp)    bl[st[tp--]]=cnt;
    42     printf("%d
    ",cnt);
    43     for(i=1;i<=n;i++)    printf("%d ",bl[i]);
    44     puts("");
    45     for(i=1;i<=cnt;i++)    printf("%d ",rt[i]);
    46     return 0;
    47 }
      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<map>
      6 #include<cmath>
      7 using namespace std;
      8 #define fi first
      9 #define se second
     10 #define mp make_pair
     11 #define pb push_back
     12 typedef long long ll;
     13 typedef unsigned long long ull;
     14 typedef pair<int,int> pii;
     15 int n,sz,m;
     16 vector<int> e[100100];
     17 int st[100100],tp,rt[100100],cnt,bl[100100];
     18 int dd[100100];
     19 struct Q
     20 {
     21     int x,y,n;
     22 }q[100100];
     23 void dfs(int u,int fa)
     24 {
     25     int i,ltp=tp;
     26     for(i=0;i<e[u].size();i++)
     27         if(e[u][i]!=fa)
     28         {
     29             dfs(e[u][i],u);
     30             if(tp-ltp>=sz)
     31             {
     32                 rt[++cnt]=u;
     33                 while(tp!=ltp)    bl[st[tp--]]=cnt;
     34             }
     35         }
     36     st[++tp]=u;
     37 }
     38 bool operator<(const Q &a,const Q &b)
     39 {
     40     return bl[a.x]==bl[b.x]?bl[a.y]<bl[b.y]:bl[a.x]<bl[b.x];
     41 }
     42 int num[100100],an;
     43 bool vis[100100];
     44 void change(int u)
     45 {
     46     if(vis[u])
     47     {
     48         num[dd[u]]--;
     49         if(num[dd[u]]==0)    an--;
     50         vis[u]=0;
     51     }
     52     else
     53     {
     54         if(num[dd[u]]==0)    an++;
     55         num[dd[u]]++;
     56         vis[u]=1;
     57     }
     58 }
     59 namespace LCA
     60 {
     61 int anc[100100][20],dep[100100],l2n=19;
     62 void dfs(int u,int fa)
     63 {
     64     int i;
     65     anc[u][0]=fa;
     66     dep[u]=dep[fa]+1;
     67     for(i=1;i<=l2n;i++)
     68         anc[u][i]=anc[anc[u][i-1]][i-1];
     69     for(i=0;i<e[u].size();i++)
     70         if(e[u][i]!=fa)
     71             dfs(e[u][i],u);
     72 }
     73 int lca(int x,int y)
     74 {
     75     int t,i;
     76     if(dep[x]<dep[y]){t=x;x=y;y=t;}
     77     for(t=dep[x]-dep[y],i=0;t>0;t>>=1,i++)
     78         if(t&1)    x=anc[x][i];
     79     if(x==y)    return x;
     80     for(i=l2n;i>=0;i--)
     81         if(anc[x][i]!=anc[y][i])
     82         {
     83             x=anc[x][i];
     84             y=anc[y][i];
     85         }
     86     return anc[x][0];
     87 }
     88 void work(int x,int y)
     89 {
     90     if(dep[x]<dep[y])    swap(x,y);
     91     while(dep[x]>dep[y])
     92     {
     93         change(x);
     94         x=anc[x][0];
     95     }
     96     while(x!=y)
     97     {
     98         change(x);change(y);
     99         x=anc[x][0];y=anc[y][0];
    100     }
    101 }
    102 }
    103 using LCA::work;
    104 using LCA::lca;
    105 int t1[100100];
    106 map<int,int> ma;
    107 int ans[100100];
    108 int main()
    109 {
    110     int i,a,b,l;
    111     scanf("%d%d",&n,&m);sz=sqrt(n+0.5);
    112     if(m==0)    return 0;
    113     for(i=1;i<=n;i++)    scanf("%d",&dd[i]),t1[++t1[0]]=dd[i];
    114     sort(t1+1,t1+t1[0]+1);t1[0]=unique(t1+1,t1+t1[0]+1)-t1-1;
    115     for(i=1;i<=t1[0];i++)    ma[t1[i]]=i;
    116     for(i=1;i<=n;i++)    dd[i]=ma[dd[i]];
    117     for(i=1;i<n;i++)
    118     {
    119         scanf("%d%d",&a,&b);
    120         e[a].pb(b);e[b].pb(a);
    121     }
    122     dfs(1,0);LCA::dfs(1,0);
    123     while(tp)    bl[st[tp--]]=cnt;
    124     for(i=1;i<=m;i++)
    125     {
    126         scanf("%d%d",&q[i].x,&q[i].y);
    127         q[i].n=i;
    128     }
    129     sort(q+1,q+m+1);
    130     work(q[1].x,q[1].y);
    131     l=lca(q[1].x,q[1].y);
    132     change(l);
    133     ans[q[1].n]=an;
    134     change(l);
    135     for(i=2;i<=m;i++)
    136     {
    137         work(q[i].x,q[i-1].x);
    138         work(q[i].y,q[i-1].y);
    139         l=lca(q[i].x,q[i].y);
    140         change(l);
    141         ans[q[i].n]=an;
    142         change(l);
    143     }
    144     for(i=1;i<=m;i++)    printf("%d
    ",ans[i]);
    145     return 0;
    146 }

    https://www.lydsy.com/JudgeOnline/problem.php?id=2589

    加强版啊。。强制在线啊

    更麻烦了,不能用莫队了

    不过做过强制在线区间众数,还是有一点类似的

    随便搞一个根节点(比如1),分块

    处理一些东西:

    fa[i]表示i的父亲

    rt[i]表示i块的“块顶”

    bl[i]表示i节点所属块

    an1[i][j]:rt[i],rt[j]间答案(除lca(rt[i],rt[j]))

    d[i][j]:rt[i]到树根的路径中权值为j的有多少个

    vv[i][j]:j是否在rt[i]到根的路径上

    对于询问(a,b),

    设ra=rt[bl[a]],rb=rt[bl[b]]

    先得到ra,rb路径上的答案(除lca(ra,rb))(这个答案已经预处理出来了)

    然后假装你得到了两个数组tt和vis,其中tt[i]表示ra到rb的路径上(除lca),权值i出现的次数;vis[i]表示i是否在ra到rb的路径上(除lca)

    (你当然没有得到这两个数组,但是设l=lca(ra,rb),那么预处理一些东西后,这两个数组的任一个元素都可以O(1)得到)

    (每一次询问时,先求出gt[i]为l到rt[bl[l]]的路径上(含l,不含rt[bl[l]])权值i出现的次数)

    (那么tt[i]=d[bl[a]][i]+d[bl[b]][i]-2*d[bl[l]][i]-2*gt[i],vis[i]=vv[bl[a]][i]^vv[bl[b]][i])

    按照莫队的方法转移就行了,最后把lca临时加上

    (显然不能直接修改,要另开空数组记录修改,得到答案后把修改还原)

    听说这种类型的分块(记录两块间答案的)也可以通过调整块大小支持带修复杂度n^(5/3)?以后再说

    理想很美好,现实很...

    我卡常失败了,本地(破机子)一个点10秒,随便找个别的机子一个点4-5秒,测了一下运算次数,大概有30亿,跟暴力差不多。。。不知道是不是写错了;在"别的机子"上,强制在线莫队大概7秒,所以应该还好吧...

    调了一个下午啊,以后再说吧

    试验中可能有效的卡常:

    1.修改时把修改的用另一个数组记录下来,后面根据记下的信息还原(直接置0),而不是反着做一遍,还原时可以用指针

    2.261行之前把bl[a],bl[b],bl[l]用单独的变量先取出来,后面直接使用

    3.261行乘号改左移;快读快写

    失败代码:

    错误记录:

    1.分块的时候要注意,最后剩下的一部分,要么加入最后一块,额外使得rt[cnt]=1,要么另开一块,使得rt[cnt]=1;跟前面不一样

    2.各种dd[x],x,bl[x]不分,代码中打了注释的就是错误记录

    3.一开始没考虑(以上说明中)gt的贡献

      1 #pragma GCC optimize(3)
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<vector>
      6 #include<map>
      7 #include<cmath>
      8 //#include<cassert>
      9 using namespace std;
     10 #define fi first
     11 #define se second
     12 #define mp make_pair
     13 #define pb push_back
     14 typedef long long ll;
     15 typedef unsigned long long ull;
     16 typedef pair<int,int> pii;
     17 int n,sz,m;
     18 vector<int> e[40100];
     19 int rt[40100],cnt,bl[40100];
     20 namespace GBLOCK
     21 {
     22 int st[40100],tp;
     23 void dfs(int u,int fa)
     24 {
     25     int i,ltp=tp;
     26     for(i=0;i<e[u].size();i++)
     27         if(e[u][i]!=fa)
     28         {
     29             dfs(e[u][i],u);
     30             if(tp-ltp>=sz)
     31             {
     32                 rt[++cnt]=u;
     33                 while(tp!=ltp)    bl[st[tp--]]=cnt;
     34             }
     35         }
     36     st[++tp]=u;
     37 }
     38 void work()
     39 {
     40     dfs(1,0);
     41     //assert(rt[cnt]==1);
     42     ++cnt;rt[cnt]=1;
     43     while(tp)    bl[st[tp--]]=cnt;
     44 }
     45 }
     46 int dd[40100];
     47 namespace LCA
     48 {
     49 int anc[40100][20],dep[40100],l2n=19;
     50 void dfs(int u,int fa)
     51 {
     52     int i;
     53     anc[u][0]=fa;
     54     dep[u]=dep[fa]+1;
     55     for(i=1;i<=l2n;i++)
     56         anc[u][i]=anc[anc[u][i-1]][i-1];
     57     for(i=0;i<e[u].size();i++)
     58         if(e[u][i]!=fa)
     59             dfs(e[u][i],u);
     60 }
     61 int lca(int x,int y)
     62 {
     63     int t,i;
     64     if(dep[x]<dep[y]){t=x;x=y;y=t;}
     65     for(t=dep[x]-dep[y],i=0;t>0;t>>=1,i++)
     66         if(t&1)    x=anc[x][i];
     67     if(x==y)    return x;
     68     for(i=l2n;i>=0;i--)
     69         if(anc[x][i]!=anc[y][i])
     70         {
     71             x=anc[x][i];
     72             y=anc[y][i];
     73         }
     74     return anc[x][0];
     75 }
     76 }
     77 int an1[210][210];
     78 int d[210][40100];
     79 bool vv[210][40100];
     80 int tt[40100];
     81 bool vis[40100];
     82 int an;
     83 void Change(int x)
     84 {
     85     if(!vis[x])
     86     {//printf("1a%d
    ",x);
     87         tt[dd[x]]++;
     88         if(tt[dd[x]]==1)    an++;
     89     }
     90     else
     91     {//printf("1b%d
    ",x);
     92         tt[dd[x]]--;
     93         if(tt[dd[x]]==0)    an--;
     94     }
     95     vis[x]^=1;
     96 }
     97 using LCA::lca;
     98 using LCA::anc;
     99 using LCA::dep;
    100 #define CLR(x) memset(x,0,sizeof(x))
    101 namespace PRE
    102 {
    103 vector<int> rts[40100];
    104 int s;
    105 void dfs1(int u,int fa)
    106 {
    107     int i;
    108     tt[dd[u]]++;vis[u]=1;
    109     for(i=0;i<rts[u].size();i++)
    110     {
    111         memcpy(d[rts[u][i]],tt,sizeof(tt));
    112         memcpy(vv[rts[u][i]],vis,sizeof(vis));
    113     }
    114     for(i=0;i<e[u].size();i++)
    115         if(e[u][i]!=fa)
    116             dfs1(e[u][i],u);
    117     tt[dd[u]]--;vis[u]=0;
    118 }
    119 void dfs2(int u,int fa)
    120 {
    121     int i;
    122     Change(u);
    123     int l=lca(rt[s],u);
    124     Change(l);
    125     for(i=0;i<rts[u].size();i++)
    126         an1[s][rts[u][i]]=an;
    127     Change(l);
    128     for(i=0;i<e[u].size();i++)
    129         if(e[u][i]!=fa)
    130             dfs2(e[u][i],u);
    131     Change(u);
    132 }
    133 void work()
    134 {
    135     int i;
    136     for(i=1;i<=cnt;i++)    rts[rt[i]].pb(i);
    137     dfs1(1,0);
    138     for(i=1;i<=cnt;i++)
    139     {
    140         s=i;
    141         dfs2(rt[s],0);
    142     }
    143 }
    144 }
    145 int t1[40100];
    146 map<int,int> ma;
    147 int main()
    148 {
    149     //freopen("/tmp/2589/3.in","r",stdin);
    150     //freopen("/tmp/2589/3.ans","w",stdout);
    151     //auto ff=fopen("/tmp/2589/1.in","r");
    152     //auto ff=fopen("t1.txt","r");
    153     //#define scanf(...) fscanf(ff,__VA_ARGS__)
    154     int i,a,b,l,x,y,ra,rb,lans=0;
    155     scanf("%d%d",&n,&m);sz=200;//
    156     for(i=1;i<=n;i++)    scanf("%d",&dd[i]),t1[++t1[0]]=dd[i];
    157     sort(t1+1,t1+t1[0]+1);t1[0]=unique(t1+1,t1+t1[0]+1)-t1-1;
    158     for(i=1;i<=t1[0];i++)    ma[t1[i]]=i;
    159     for(i=1;i<=n;i++)    dd[i]=ma[dd[i]];
    160     for(i=1;i<n;i++)
    161     {
    162         scanf("%d%d",&a,&b);
    163         e[a].pb(b);e[b].pb(a);
    164     }
    165     GBLOCK::work();LCA::dfs(1,0);
    166     PRE::work();
    167     //#undef scanf
    168 /*
    169     #undef scanf
    170     putchar('a');
    171     for(i=1;i<=n;i++)    printf("%d ",bl[i]);
    172     puts("");
    173     //scanf("%d",new int);
    174     puts("b");
    175     for(i=1;i<=cnt;i++)
    176     {
    177         for(int j=1;j<=cnt;j++)
    178         {
    179             printf("%d ",an1[i][j]);
    180         }
    181         puts("");
    182     }
    183     //scanf("%d",new int);
    184     putchar('c');
    185     for(i=1;i<=cnt;i++)    printf("%d ",rt[i]);
    186     puts("");
    187     //scanf("%d",new int);
    188     putchar('d');
    189     for(i=1;i<=n;i++)    printf("%d ",tt[i]);
    190     puts("");
    191     putchar('e');
    192     for(i=1;i<=n;i++)    printf("%d ",vis[i]);
    193     puts("");
    194     putchar('f');
    195     for(i=1;i<=cnt;i++)
    196     {
    197         for(int j=1;j<=n;j++)
    198         {
    199             printf("%d$%d ",vv[i][j],d[i][j]);
    200         }
    201         puts("");
    202     }
    203 */
    204 /*
    205 {
    206     int x=187,y=rt[bl[187]];
    207     if(dep[x]<dep[y])    swap(x,y);
    208     while(dep[x]>dep[y])
    209     {
    210         printf("n%d
    ",x);
    211         x=anc[x][0];
    212     }
    213     //assert(x==y);
    214 
    215     while(x!=y){
    216     printf("ttt%d %d %d %d
    ",x,y,dep[x],dep[y]);
    217     x=anc[x][0];y=anc[y][0];
    218     }
    219     printf("ttt%d %d %d %d
    ",x,y,dep[x],dep[y]);
    220 }
    221 */
    222     for(i=1;i<=m;i++)
    223     {
    224         scanf("%d%d",&a,&b);a^=lans;
    225         if(bl[a]==bl[b])
    226         {
    227             an=0;
    228             x=a;y=b;
    229             if(dep[x]<dep[y])    swap(x,y);
    230             while(dep[x]>dep[y])
    231             {
    232                 Change(x);
    233                 x=anc[x][0];
    234             }
    235             while(x!=y)
    236             {
    237                 Change(x);Change(y);
    238                 x=anc[x][0];y=anc[y][0];
    239             }
    240             Change(x);
    241             lans=an;
    242             Change(x);
    243             //printf("c%d %d
    ",a,b);
    244             x=a;y=b;
    245             if(dep[x]<dep[y])    swap(x,y);
    246             while(dep[x]>dep[y])
    247             {
    248                 Change(x);
    249                 x=anc[x][0];
    250             }
    251             while(x!=y)
    252             {
    253                 Change(x);Change(y);
    254                 x=anc[x][0];y=anc[y][0];
    255             }
    256         }
    257         else
    258         {
    259             ra=rt[bl[a]];rb=rt[bl[b]];
    260             l=lca(ra,rb);
    261             #define GD(i) (tt[i]+d[bl[a]][i]+d[bl[b]][i]-2*d[bl[l]][i])//
    262             #define GV(i) (vis[i]^vv[bl[a]][i]^vv[bl[b]][i])
    263             an=an1[bl[a]][bl[b]];//
    264             //
    265             x=l;
    266             while(x!=rt[bl[l]])
    267             {
    268                 //printf("d%d
    ",x);
    269                 tt[dd[x]]-=2;
    270                 //if(GD(dd[x])==0)    an--;
    271                 //vis[x]^=1;
    272                 x=anc[x][0];
    273             }
    274             //
    275             x=a;y=ra;
    276             //printf("1s%d
    ",GV(5));
    277             while(dep[x]>dep[y])
    278             {
    279                 //printf("tt%d %d %d %d %d %d %d %d
    ",x,y,an,GD(dd[x]),tt[dd[x]],d[1][dd[x]],d[2][dd[x]],d[2][dd[x]]);
    280                 if(!GV(x))//if(!GV(dd[x]))//
    281                 {
    282                     tt[dd[x]]++;
    283                     if(GD(dd[x])==1)    an++;
    284                     //putchar('_');
    285                     //printf("$%d$",GD(dd[x]));
    286                 }
    287                 else
    288                 {
    289                     tt[dd[x]]--;
    290                     if(GD(dd[x])==0)    an--;
    291                     //putchar('-');
    292                 }
    293                 vis[x]^=1;//vis[dd[x]]^=1;
    294                 //printf("t%d %d %d %d %d %d %d %d %d
    ",ra,rb,l,a,b,bl[a],bl[b],x,an);
    295                 x=anc[x][0];
    296             }
    297             //不需要x!=y的,因为x一定是rt[bl[x]]的子树中节点
    298             //assert(x==y);
    299             //if(x!=y)    printf("!!%d %d
    ",x,y);
    300             x=b;y=rb;
    301             while(dep[x]>dep[y])
    302             {
    303                 if(!GV(x))//if(!GV(dd[x]))//
    304                 {
    305                     tt[dd[x]]++;
    306                     if(GD(dd[x])==1)    an++;
    307                     //putchar('_');
    308                 }
    309                 else
    310                 {
    311                     tt[dd[x]]--;
    312                     if(GD(dd[x])==0)    an--;
    313                     //putchar('-');
    314                 }
    315                 vis[x]^=1;//vis[dd[x]]^=1;
    316                 //printf("p%d %d %d %d %d %d %d %d %d
    ",ra,rb,l,a,b,bl[a],bl[b],x,an);
    317                 x=anc[x][0];
    318             }
    319             x=lca(a,b);
    320             //printf("g%d
    ",x);
    321             if(!GV(x))//if(!GV(dd[x]))//
    322             {
    323                 tt[dd[x]]++;
    324                 if(GD(dd[x])==1)    an++;
    325                 //putchar('_');
    326             }
    327             else
    328             {
    329                 tt[dd[x]]--;
    330                 if(GD(dd[x])==0)    an--;
    331                 //putchar('-');
    332             }
    333             vis[x]^=1;//vis[dd[x]]^=1;
    334             lans=an;
    335             if(!GV(x))//if(!GV(dd[x]))//
    336             {
    337                 tt[dd[x]]++;
    338             }
    339             else
    340             {
    341                 tt[dd[x]]--;
    342             }
    343             vis[x]^=1;//vis[dd[x]]^=1;
    344             x=a;y=ra;
    345             while(dep[x]>dep[y])
    346             {
    347                 if(!GV(x))//if(!GV(dd[x]))//
    348                 {
    349                     tt[dd[x]]++;
    350                 }
    351                 else
    352                 {
    353                     tt[dd[x]]--;
    354                 }
    355                 vis[x]^=1;//vis[dd[x]]^=1;
    356                 x=anc[x][0];
    357             }
    358             //assert(x==y);
    359             //if(x!=y)    printf("!!%d %d
    ",x,y);
    360             x=b;y=rb;
    361             while(dep[x]>dep[y])
    362             {
    363                 if(!GV(x))//if(!GV(dd[x]))//
    364                 {
    365                     tt[dd[x]]++;
    366                 }
    367                 else
    368                 {
    369                     tt[dd[x]]--;
    370                 }
    371                 vis[x]^=1;//vis[dd[x]]^=1;
    372                 x=anc[x][0];
    373             }
    374             //
    375             x=l;
    376             while(x!=rt[bl[l]])
    377             {
    378                 tt[dd[x]]+=2;
    379                 //vis[x]^=1;
    380                 x=anc[x][0];
    381             }
    382             //
    383             #undef G
    384         }
    385         printf("%d
    ",lans);
    386         //for(int i=1;i<=n;i++)    assert(tt[i]==0);
    387         //for(int i=1;i<=n;i++)    assert(vis[i]==0);
    388     }
    389     return 0;
    390 }

    可以发现这种分块方法好像可以搬到括号序上。。。

    要能够对于一个k,O(1)求区间内有多少个数,仅出现一次,且“对应数”等于k

    并不能直接搬!因为不能前缀和了

    。。。并不能研究出来怎么搞(除非多一个log),又一次失败了

    失败代码2:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<map>
      6 using namespace std;
      7 #define fi first
      8 #define se second
      9 #define mp make_pair
     10 #define pb push_back
     11 typedef long long ll;
     12 typedef unsigned long long ull;
     13 typedef pair<int,int> pii;
     14 const int N=40;
     15 const int ss=40;
     16 int n,m,a1[N+100];
     17 int t1[N+100];
     18 map<int,int> ma;
     19 vector<int> e[N+100];
     20 namespace LCA
     21 {
     22 int anc[N+100][20],dep[N+100],l2n=19;
     23 void dfs(int u,int fa)
     24 {
     25     int i;
     26     anc[u][0]=fa;
     27     dep[u]=dep[fa]+1;
     28     for(i=1;i<=l2n;i++)
     29         anc[u][i]=anc[anc[u][i-1]][i-1];
     30     for(i=0;i<e[u].size();i++)
     31         if(e[u][i]!=fa)
     32             dfs(e[u][i],u);
     33 }
     34 int lca(int a1,int y)
     35 {
     36     int t,i;
     37     if(dep[a1]<dep[y]){t=a1;a1=y;y=t;}
     38     for(t=dep[a1]-dep[y],i=0;t>0;t>>=1,i++)
     39         if(t&1)    a1=anc[a1][i];
     40     if(a1==y)    return a1;
     41     for(i=l2n;i>=0;i--)
     42         if(anc[a1][i]!=anc[y][i])
     43         {
     44             a1=anc[a1][i];
     45             y=anc[y][i];
     46         }
     47     return anc[a1][0];
     48 }
     49 }
     50 using LCA::lca;
     51 int pl[N+100],dd[2*N+100];
     52 void dfs(int u,int fa)
     53 {
     54     int i;
     55     dd[++dd[0]]=u;pl[u]=dd[0];
     56     for(i=0;i<e[u].size();i++)
     57         if(e[u][i]!=fa)
     58             dfs(e[u][i],u);
     59     dd[++dd[0]]=u;
     60 }
     61 bool vis[N+100];int num[N+100];
     62 int an,sz,sz1;
     63 int bl[2*N+100];
     64 int st[ss+10],ed[ss+10];
     65 int d[ss+10][N+100];//d[i][j]:i块(含)之前j出现次数
     66 bool vv[ss+10][N+100];
     67 int an1[ss+10][ss+10];//an1[i][j]:i块到j块(均含)间答案
     68 void change(int u)
     69 {
     70     if(vis[u])
     71     {
     72         num[a1[u]]--;
     73         if(num[a1[u]]==0)    an--;
     74     }
     75     else
     76     {
     77         if(num[a1[u]]==0)    an++;
     78         num[a1[u]]++;
     79     }
     80     vis[u]^=1;
     81 }
     82 int h1[N+100],tp1;
     83 int main()
     84 {
     85     int i,j,k,x,y,a,b,aa,bb,l,lans=0;
     86     scanf("%d%d",&n,&m);sz=2;
     87     for(i=1;i<=n;i++)    scanf("%d",&a1[i]),t1[++t1[0]]=a1[i];
     88     sort(t1+1,t1+t1[0]+1);t1[0]=unique(t1+1,t1+t1[0]+1)-t1-1;
     89     for(i=1;i<=t1[0];i++)    ma[t1[i]]=i;
     90     for(i=1;i<=n;i++)    a1[i]=ma[a1[i]];
     91     for(i=1;i<n;i++)
     92     {
     93         scanf("%d%d",&x,&y);
     94         e[x].pb(y);e[y].pb(x);
     95     }
     96     LCA::dfs(1,0);dfs(1,0);
     97     for(i=1;i<=dd[0];i++)    bl[i]=(i-1)/sz;
     98     sz1=bl[dd[0]];
     99     for(i=0;i<sz1;i++)    st[i]=i*sz+1,ed[i]=(i+1)*sz;
    100     st[sz1]=sz1*sz+1;ed[sz1]=dd[0];
    101     for(i=0;i<=sz1;i++)
    102     {
    103         for(j=st[i];j<=ed[i];j++)    change(dd[j]);
    104         memcpy(vv[i],vis,sizeof(vis));
    105         memcpy(d[i],num,sizeof(num));
    106     }
    107     memset(num,0,sizeof(num));
    108     memset(vis,0,sizeof(vis));
    109     an=0;
    110     for(i=0;i<=sz1;i++)
    111     {
    112         for(j=i;j<=sz1;j++)
    113         {
    114             for(k=st[j];k<=ed[j];k++)    change(dd[k]);
    115             an1[i][j]=an;
    116         }
    117         memset(num,0,sizeof(num));
    118         memset(vis,0,sizeof(vis));
    119         an=0;
    120     }
    121     for(i=1;i<=m;i++)
    122     {
    123         scanf("%d%d",&aa,&bb);
    124         a=pl[aa];b=pl[bb];
    125         if(bl[a]==bl[b]||bl[a]+1==bl[b])
    126         {
    127             an=0;
    128             for(j=a;j<=b;j++)    change(dd[j]),h1[++tp1]=dd[j];
    129             l=lca(aa,bb);
    130             if(!vis[aa])    change(aa),h1[++tp1]=aa;
    131             if(!vis[bb])    change(bb),h1[++tp1]=bb;
    132             if(!vis[l])    change(l),h1[++tp1]=l;
    133         }
    134         else
    135         {
    136             #define GV(u) (vis[u]^vv[bl[a]][u]^vv[bl[b]-1][u])
    137             #define GN(u) (num[u]+d[bl[b]-1][u]-d[bl[a]][u])
    138             #define CG(u) {
    139                 if(GV(u))
    140                 {
    141                     num[a1[u]]--;
    142                     if(GN(a1[u])==0)    an--;
    143                 }
    144                 else
    145                 {
    146                     if(GN(a1[u])==0)    an++;
    147                     num[a1[u]]++;
    148                 }
    149                 h1[++tp1]=u;
    150                 vis[u]^=1;
    151             }
    152             an=an1[bl[a]+1][bl[b]-1];
    153             for(j=a;j<=ed[bl[a]];j++)    CG(dd[j]);
    154             for(j=st[bl[b]];j<=b;j++)    CG(dd[j]);
    155             if(!GV(aa))    CG(aa);
    156             if(!GV(bb))    CG(bb);
    157             l=lca(aa,bb);
    158             if(!GV(l))    CG(l);
    159         }
    160         lans=an;
    161         printf("%d
    ",lans);
    162         for(j=1;j<=tp1;j++)    num[a1[h1[j]]]=vis[h1[j]]=0;
    163     }
    164     return 0;
    165 }

    卡常最终版本:

      1 #pragma GCC optimize(3)
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<vector>
      6 #include<map>
      7 #include<cmath>
      8 using namespace std;
      9 #define fi first
     10 #define se second
     11 #define mp make_pair
     12 #define pb push_back
     13 typedef long long ll;
     14 typedef unsigned long long ull;
     15 typedef pair<int,int> pii;
     16 int n,sz,m;
     17 vector<int> e[40100];
     18 int rt[40100],cnt,bl[40100];
     19 namespace GBLOCK
     20 {
     21 int st[40100],tp;
     22 void dfs(int u,int fa)
     23 {
     24     int i,ltp=tp;
     25     for(i=0;i<e[u].size();++i)
     26         if(e[u][i]!=fa)
     27         {
     28             dfs(e[u][i],u);
     29             if(tp-ltp>=sz)
     30             {
     31                 rt[++cnt]=u;
     32                 while(tp!=ltp)    bl[st[tp--]]=cnt;
     33             }
     34         }
     35     st[++tp]=u;
     36 }
     37 void work()
     38 {
     39     dfs(1,0);
     40     ++cnt;rt[cnt]=1;
     41     while(tp)    bl[st[tp--]]=cnt;
     42 }
     43 }
     44 int dd[40100];
     45 namespace LCA
     46 {
     47 int anc[40100][20],dep[40100],l2n=19;
     48 void dfs(int u,int fa)
     49 {
     50     int i;
     51     anc[u][0]=fa;
     52     dep[u]=dep[fa]+1;
     53     for(i=1;i<=l2n;++i)
     54         anc[u][i]=anc[anc[u][i-1]][i-1];
     55     for(i=0;i<e[u].size();++i)
     56         if(e[u][i]!=fa)
     57             dfs(e[u][i],u);
     58 }
     59 int lca(int x,int y)
     60 {
     61     int t,i;
     62     if(dep[x]<dep[y]){t=x;x=y;y=t;}
     63     for(t=dep[x]-dep[y],i=0;t>0;t>>=1,++i)
     64         if(t&1)    x=anc[x][i];
     65     if(x==y)    return x;
     66     for(i=l2n;i>=0;--i)
     67         if(anc[x][i]!=anc[y][i])
     68         {
     69             x=anc[x][i];
     70             y=anc[y][i];
     71         }
     72     return anc[x][0];
     73 }
     74 }
     75 int an1[210][210];
     76 int d[210][40100];
     77 bool vv[210][40100];
     78 int tt[40100];
     79 bool vis[40100];
     80 int an;
     81 void Change(int x)
     82 {
     83     if(vis[x])
     84     {
     85         --tt[dd[x]];
     86         if(tt[dd[x]]==0)    --an;
     87     }
     88     else
     89     {
     90         ++tt[dd[x]];
     91         if(tt[dd[x]]==1)    ++an;
     92     }
     93     vis[x]^=1;
     94 }
     95 using LCA::lca;
     96 using LCA::anc;
     97 using LCA::dep;
     98 #define CLR(x) memset(x,0,sizeof(x))
     99 namespace PRE
    100 {
    101 vector<int> rts[40100];
    102 int s;
    103 void dfs1(int u,int fa)
    104 {
    105     int i;
    106     ++tt[dd[u]];vis[u]=1;
    107     for(i=0;i<rts[u].size();++i)
    108     {
    109         memcpy(d[rts[u][i]],tt,sizeof(tt));
    110         memcpy(vv[rts[u][i]],vis,sizeof(vis));
    111     }
    112     for(i=0;i<e[u].size();++i)
    113         if(e[u][i]!=fa)
    114             dfs1(e[u][i],u);
    115     --tt[dd[u]];vis[u]=0;
    116 }
    117 void dfs2(int u,int fa)
    118 {
    119     int i;
    120     Change(u);
    121     int l=lca(rt[s],u);
    122     Change(l);
    123     for(i=0;i<rts[u].size();++i)
    124         an1[s][rts[u][i]]=an;
    125     Change(l);
    126     for(i=0;i<e[u].size();++i)
    127         if(e[u][i]!=fa)
    128             dfs2(e[u][i],u);
    129     Change(u);
    130 }
    131 void work()
    132 {
    133     int i;
    134     for(i=1;i<=cnt;++i)    rts[rt[i]].pb(i);
    135     dfs1(1,0);
    136     for(i=1;i<=cnt;++i)
    137     {
    138         s=i;
    139         dfs2(rt[s],0);
    140     }
    141 }
    142 }
    143 int t1[40100];
    144 map<int,int> ma;
    145 int h1[40100],*tp1=h1;
    146 inline void read(int &x) {
    147     x=0;char ch=getchar();
    148     while(ch>'9'||ch<'0')ch=getchar();
    149     while(ch>='0'&&ch<='9'){x*=10;x+=(ch-'0');ch=getchar();}
    150 }
    151 inline void write(int x) {
    152     if(x>9) write(x/10);
    153     putchar(x%10+'0');
    154 }
    155 int main()
    156 {
    157     //freopen("/tmp/2589/2.in","r",stdin);
    158     //freopen("/tmp/2589/2.ans","w",stdout);
    159     int i,bla,blb,bll,a,b,l,x,y,ra,rb,rl,lans=0,*it;
    160     bool *vvbla,*vvblb;int *dbla,*dblb,*dbll;
    161     read(n);read(m);sz=300;
    162     for(i=1;i<=n;++i)    scanf("%d",&dd[i]),t1[++t1[0]]=dd[i];
    163     sort(t1+1,t1+t1[0]+1);t1[0]=unique(t1+1,t1+t1[0]+1)-t1-1;
    164     for(i=1;i<=t1[0];++i)    ma[t1[i]]=i;
    165     for(i=1;i<=n;++i)    dd[i]=ma[dd[i]];
    166     for(i=1;i<n;++i)
    167     {
    168         read(a);read(b);
    169         e[a].pb(b);e[b].pb(a);
    170     }
    171     GBLOCK::work();LCA::dfs(1,0);
    172     PRE::work();
    173     for(i=1;i<=m;++i)
    174     {
    175         read(a);read(b);a^=lans;
    176         if(bl[a]==bl[b])
    177         {
    178             an=0;
    179             x=a;y=b;
    180             if(dep[x]<dep[y])    swap(x,y);
    181             while(dep[x]>dep[y])
    182             {
    183                 Change(x);*(++tp1)=x;
    184                 x=anc[x][0];
    185             }
    186             while(x!=y)
    187             {
    188                 Change(x);Change(y);*(++tp1)=x;*(++tp1)=y;
    189                 x=anc[x][0];y=anc[y][0];
    190             }
    191             Change(x);*(++tp1)=x;
    192             lans=an;
    193         }
    194         else
    195         {
    196             bla=bl[a];blb=bl[b];
    197             ra=rt[bla];rb=rt[blb];
    198             l=lca(ra,rb);bll=bl[l];rl=rt[bll];
    199             dbla=d[bla];dblb=d[blb];dbll=d[bll];
    200             vvbla=vv[bla];vvblb=vv[blb];
    201             #define GD(i) (tt[i]+dbla[i]+dblb[i]-(dbll[i]<<1))
    202             #define GV(i) (vis[i]^vvbla[i]^vvblb[i])
    203             an=an1[bla][blb];
    204             x=l;
    205             while(x!=rl)
    206             {
    207                 tt[dd[x]]-=2;*(++tp1)=x;
    208                 x=anc[x][0];
    209             }
    210             x=a;y=ra;
    211             while(x!=y)
    212             {
    213                 if(GV(x))
    214                 {
    215                     --tt[dd[x]];
    216                     if(GD(dd[x])==0)    --an;
    217                 }
    218                 else
    219                 {
    220                     ++tt[dd[x]];
    221                     if(GD(dd[x])==1)    ++an;
    222                 }
    223                 *(++tp1)=x;
    224                 vis[x]^=1;
    225                 x=anc[x][0];
    226             }
    227             x=b;y=rb;
    228             while(x!=y)
    229             {
    230                 if(GV(x))
    231                 {
    232                     --tt[dd[x]];
    233                     if(GD(dd[x])==0)    --an;
    234                 }
    235                 else
    236                 {
    237                     ++tt[dd[x]];
    238                     if(GD(dd[x])==1)    ++an;
    239                 }
    240                 *(++tp1)=x;
    241                 vis[x]^=1;
    242                 x=anc[x][0];
    243             }
    244             x=lca(a,b);
    245             if(GV(x))
    246             {
    247                 --tt[dd[x]];
    248                 if(GD(dd[x])==0)    --an;
    249             }
    250             else
    251             {
    252                 ++tt[dd[x]];
    253                 if(GD(dd[x])==1)    ++an;
    254             }
    255             *(++tp1)=x;
    256             vis[x]^=1;
    257             lans=an;
    258             #undef G
    259         }
    260         write(lans);putchar('
    ');
    261         for(it=h1+1;it<=tp1;++it)    tt[dd[*it]]=vis[*it]=0;
    262         tp1=h1;
    263     }
    264     return 0;
    265 }
  • 相关阅读:
    HTML <input> 标签
    HTML5 <input> type 属性
    静态页面与动态页面
    string::size_type 页73 size_t 页90
    template method(模板方法)
    C++中创建对象的时候加括号和不加括号的区别(转)
    _declspec(dllexport)和.def(转)
    智能指针
    C++中的delete加深认识
    工厂方法(整理自李建忠<C++设计模式>视频)
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9463519.html
Copyright © 2011-2022 走看看