zoukankan      html  css  js  c++  java
  • bzoj 3757: 苹果树

    树分块,然后莫队,不知道为什么RE了,挖坑++

    为了处理由一个转移到下一个,(莫队嘛),要做的就是把上次询问的左端点s1,和这次询问的左端点s2,求lca,然后把路径上的操作去反,右端点一样的。

    为什么对,有神犇用公式证明的,然后本蒟蒻画了个草图,一看就很显然2333,但是根节点还是不显然的,,,(还是能将就着看的233)

      1 #include<bits/stdc++.h>
      2 #define N 1000005
      3 #define LL long long
      4 #define inf 0x3f3f3f3f
      5 using namespace std;
      6 inline int ra()
      7 {
      8     int x=0,f=1; char ch=getchar();
      9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
     10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
     11     return x*f;
     12 }
     13 int bin[20];
     14 int n,m,cnt,ans1;
     15 int top,ind,block,blocknum,root;
     16 int ans[100005],p[100005];
     17 int fa[100005][20],deep[100005];
     18 int c[100005],st[100005],dfn[100005],belong[100005];
     19 bool vis[100005];
     20 struct data{int to,next;}e[200005];
     21 int head[100005];
     22 struct query{int x,y,a,b,id;}q[200005];
     23 bool operator < (query a, query b){
     24     if (belong[a.x]==belong[b.x]) return dfn[a.y]<dfn[b.y];
     25     return belong[a.x]<belong[b.x];
     26 }
     27 void insert(int x, int y) {e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;}
     28 int dfs(int x)
     29 {
     30     int size=0;
     31     dfn[x]=++ind;
     32     for (int i=1; i<=18; i++)
     33         if (deep[x]>=bin[i])
     34             fa[x][i]=fa[fa[x][i-1]][i-1];
     35         else break;
     36     for (int i=head[x];i;i=e[i].next)
     37         if (e[i].to!=fa[x][0])
     38         {
     39             deep[e[i].to]=deep[x]+1;
     40             fa[e[i].to][0]=x;
     41             size+=dfs(e[i].to);
     42             if (size>=block) 
     43             {
     44                 blocknum++;
     45                 for (int k=1; k<=size; k++)
     46                     belong[st[top--]]=blocknum;
     47                 size=0;
     48             }
     49         }
     50     st[++top]=x;
     51     return size+1;
     52 }
     53 int lca(int x, int y)
     54 {
     55     if (deep[x]<deep[y]) swap(x,y);
     56     int t=deep[x]-deep[y];
     57     for (int i=0; bin[i]<=t; i++)
     58         if (t&bin[i]) x=fa[x][i];
     59     for (int i=18; i>=0; i--)
     60         if (fa[x][i]!=fa[y][i])
     61             x=fa[x][i],y=fa[y][i];
     62     if (x==y) return x;
     63     return fa[x][0];
     64 }
     65 void rever(int x)
     66 {
     67     if (!vis[x]) {vis[x]=1; p[c[x]]++; if (p[c[x]]==1) ans1++;}
     68     else {vis[x]=0; p[c[x]]--; if (p[c[x]]==0) ans1--;}
     69 }
     70 void solve(int x, int y)
     71 {
     72     while (x!=y)
     73         if (deep[x]>deep[y]) rever(x),x=fa[x][0];
     74         else rever(y),y=fa[y][0];
     75 }
     76 int main()
     77 {
     78     bin[0]=1; for (int i=1; i<20; i++) bin[i]=bin[i-1]<<1;
     79     n=ra(); m=ra();
     80     block=sqrt(n);
     81     for (int i=1; i<=n; i++) c[i]=ra();
     82     for (int i=1; i<=n; i++)
     83     {
     84         int x=ra(),y=ra();
     85         if (!x) root=y;
     86         else if (!y) root=x;
     87         else insert(x,y),insert(y,x);
     88     }
     89     dfs(root); blocknum++;
     90     while (top) belong[st[top--]]=blocknum;
     91     for (int i=1; i<=m; i++)
     92     {
     93         q[i].x=ra(),q[i].y=ra();
     94         if (dfn[q[i].x]>dfn[q[i].y]) swap(q[i].x,q[i].y);
     95         q[i].a=ra(); q[i].b=ra(); q[i].id=i;
     96     }
     97     sort(q+1,q+m+1);
     98     int t=lca(q[1].x,q[1].y);
     99     solve(q[1].x,q[1].y); rever(t);
    100     ans[q[1].id]=ans1;
    101     if (p[q[1].a] && p[q[1].b] && q[1].a!=q[1].b) ans[q[1].id]--;
    102     rever(t);
    103     for (int i=2; i<=m; i++)
    104     {
    105         solve(q[i-1].x,q[i].x);
    106         solve(q[i-1].y,q[i].y);
    107         int t=lca(q[i].x,q[i].y);
    108         rever(t);
    109         ans[q[i].id]=ans1;
    110         if (p[q[i].a] && p[q[i].b] && q[i].a!=q[i].b) ans[q[i].id]--;
    111         rever(t);
    112     }
    113     for (int i=1; i<=m; i++) printf("%d
    ",ans[i]);
    114     return 0; 
    115 }
  • 相关阅读:
    MySQL删除重复数据
    C#如何实现Object与byte[]的互相转换
    远程桌面连接(转)
    WEB标准学习路程之"CSS":2.字体font
    WEB标准学习路程之"CSS":3.背景Background属性
    WEB标准学习路程之"入门篇":8.XHTML代码规范
    WEB标准学习路程之"CSS":9.常用选择符
    WEB标准学习路程之"CSS":1.什么是样式表
    WEB标准学习路程之"入门篇":9.校验及常见错误
    WEB标准学习路程之"CSS":4.尺寸Dimensions属性
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6435584.html
Copyright © 2011-2022 走看看