• bzoj3757 苹果树


      莫队算法,先处理dfs序,然后将询问进行一下处理,假设询问x,y两点,x的的dfs序区间是[xl,xr],y的dfs序是[yl,yr],那么这两个区间如果包含,那么询问区间[min(xl,yl),max(xl,yl)],否则询问区间[min(xr,yr),max(xl,yl)]。对于算法当前处理的一个区间的删除插入操作,假设要判断一个点x是否出现在当前区间维护的路径中,如果其dfs区间被当前区间包含或者其记录的出现次数为0,说明该点其实是不存在的,否则存在。

      代码

      

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define N 2000010
      4 using namespace std;
      5 int dp,p[N],pre[N],tt[N],l[N],r[N],tot,o[N];
      6 int L,R,ans[N],sum[N],cnt,flag1[N],flag2[N],flag3[N],colsum[N];
      7 int n,m,i,col[N],a,b;
      8 struct g{
      9     int l,r,ca,cb,id;
     10 }q[N];
     11 void link(int x,int y)
     12 {
     13     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
     14 }
     15 void dfs(int x,int fa)
     16 {
     17     int i=p[x];
     18     l[x]=++tot;
     19     o[tot]=x;
     20     while (i)
     21     {
     22         if (tt[i]!=fa)
     23         {
     24             dfs(tt[i],x);
     25             o[++tot]=x;
     26         }
     27         i=pre[i];
     28     }
     29     if (tot==l[x]) o[++tot]=x;
     30     r[x]=tot;
     31 }
     32 void cc(int x,int w)
     33 {
     34     int t=o[x];
     35     if (t==0) return;
     36     sum[t]+=w;
     37     if (x==l[t]) if (w==-1) flag1[t]=0;else flag1[t]=1;
     38     if (x==r[t]) if (w==-1) flag2[t]=0;else flag2[t]=1;
     39     if ((sum[t])&&((flag1[t]&&flag2[t])==0))
     40     {
     41         if (!flag3[t])
     42         {
     43             if (colsum[col[t]]==0) cnt++;
     44             colsum[col[t]]++;
     45         }
     46         flag3[t]=1;
     47     }
     48     else
     49     {
     50         if (flag3[t])
     51         {
     52             if (colsum[col[t]]==1) cnt--;
     53             colsum[col[t]]--;
     54         }
     55         flag3[t]=0;
     56     }
     57 }
     58 bool cmp(g a,g b)
     59 {
     60     if (a.l/500==b.l/500)
     61     return a.r<b.r;
     62     return a.l/500<b.l/500;
     63 }
     64 int main()
     65 {
     66     scanf("%d%d",&n,&m);
     67     for (i=1;i<=n;i++)
     68         scanf("%d",&col[i]);
     69     for (i=1;i<=n;i++)
     70     {
     71         scanf("%d%d",&a,&b);
     72         link(a,b);link(b,a);
     73     }
     74     dfs(0,-1);
     75     for (i=1;i<=m;i++)
     76     {
     77         scanf("%d%d%d%d",&q[i].l,&q[i].r,&q[i].ca,&q[i].cb);q[i].id=i;
     78         int ta=q[i].l;int tb=q[i].r;
     79         if (r[ta]<l[tb]) q[i].l=r[ta],q[i].r=l[tb];
     80         else
     81         if (r[tb]<l[ta]) q[i].l=r[tb],q[i].r=l[ta];
     82         else
     83         if (l[ta]<l[tb]) q[i].l=l[ta],q[i].r=l[tb];
     84         else q[i].l=l[tb],q[i].r=l[ta];
     85     }
     86 
     87     sort(q+1,q+1+m,cmp);
     88     L=1;R=0;
     89     for (i=1;i<=m;i++)
     90     {
     91         while (R<q[i].r)R++,cc(R,1);
     92         while (R>q[i].r)cc(R,-1),R--;
     93         while (L<q[i].l)cc(L,-1),L++;
     94         while (L>q[i].l)L--,cc(L,1);
     95         ans[q[i].id]=cnt;
     96         if (colsum[q[i].ca]&&colsum[q[i].cb]&&(q[i].ca!=q[i].cb)) ans[q[i].id]--;
     97     }
     98     for (i=1;i<=m;i++)
     99         printf("%d
    ",ans[i]);
    100 }
  • 相关阅读:
    gdbinit理解
    debug套路
    node 版本升级
    工作方式
    vscode 插件编写
    函数闭包与装饰器
    高阶函数与递归
    函数嵌套及作用域
    函数
    文件处理
  • 原文地址:https://www.cnblogs.com/fzmh/p/5404808.html
Copyright © 2020-2023  润新知