zoukankan      html  css  js  c++  java
  • hdu5081

    题意有点绕,不过读懂了之后并不难

    以Si结尾容易想到ac自动机,建好ac自动机并将fail指针反向即可得到一棵树

    那么操作1就是将若干个子树的并中的节点全部权值+1

    操作2就是将求若干个节点到根的路径的并中的节点的权值和

    操作1不难用dfs序将子树并转化为区间并然后线段树区间加

    操作2呢,我们进行树链剖分,对于每条重链,在重链头记录一下这条重链之前询问到哪个位置了

    因为每个点到根的路径都是若干重链的若干前缀,这样问题就解决了

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 typedef long long ll;
      5 int go[100010][27],a[500010],fa[100010],laz[400010],l[100010],r[100010],c[100010],q[100010],s[100010],nex[100010],top[100010],f[100010],d[100010];
      6 int n,m,k,t,ch;
      7 vector<int> g[100010];
      8 bool v[100010];
      9 ll tr[400010];
     10 char ss[2];
     11 
     12 bool cmp(int a,int b)
     13 {
     14     if (l[a]==l[b]) return r[a]<r[b];
     15     return l[a]<l[b];
     16 }
     17 
     18 void bfs()
     19 {
     20      int h=1,r=0;
     21      for (int i=0; i<26; i++)
     22        if (go[0][i])
     23        {
     24           g[1].push_back(go[0][i]+1);
     25           q[++r]=go[0][i];
     26        }
     27      while (h<=r)
     28      {
     29            int x=q[h++];
     30            for (int i=0; i<26; i++)
     31              if (go[x][i])
     32              {
     33                 int y=go[x][i];
     34                 q[++r]=y;
     35                 int j=f[x];
     36                 while (j>0&&!go[j][i]) j=f[j];
     37                 f[y]=go[j][i];
     38                 g[go[j][i]+1].push_back(y+1);
     39              }
     40      }
     41 }
     42 
     43 void dfs(int x)
     44 {
     45     s[x]=1;
     46     for (int i=0; i<g[x].size(); i++)
     47     {
     48         int y=g[x][i];
     49        // cout <<x<<" "<<y<<endl;
     50         d[y]=d[x]+1;
     51         fa[y]=x;
     52         dfs(y);
     53         s[x]+=s[x];
     54     }
     55 }
     56 
     57 void get(int x)
     58 {
     59     l[x]=++t;
     60     int q=0;
     61     for (int i=0; i<g[x].size(); i++)
     62     {
     63         int y=g[x][i];
     64         if (s[y]>s[q]) q=y;
     65     }
     66     if (q)
     67     {
     68         top[q]=top[x];
     69         get(q);
     70     }
     71     nex[x]=q;
     72     for (int i=0; i<g[x].size(); i++)
     73     {
     74         int y=g[x][i];
     75         if (y!=q)
     76         {
     77             top[y]=y;
     78             get(y);
     79         }
     80     }
     81     r[x]=t;
     82 }
     83 
     84 void push(int i,int l,int r)
     85 {
     86     int m=(l+r)>>1;
     87     tr[i*2]+=1ll*laz[i]*(m+1-l);
     88     tr[i*2+1]+=1ll*laz[i]*(r-m);
     89     laz[i*2]+=laz[i];
     90     laz[i*2+1]+=laz[i];
     91     laz[i]=0;
     92 }
     93 
     94 void add(int i,int l,int r,int x,int y)
     95 {
     96     if (x<=l&&y>=r)
     97     {
     98         tr[i]+=(r-l+1);
     99         laz[i]++;
    100     }
    101     else {
    102         int m=(l+r)>>1;
    103         if (laz[i]) push(i,l,r);
    104         if (x<=m) add(i*2,l,m,x,y);
    105         if (y>m) add(i*2+1,m+1,r,x,y);
    106         tr[i]=tr[i*2]+tr[i*2+1];
    107     }
    108 }
    109 
    110 ll ask(int i,int l,int r,int x,int y)
    111 {
    112     if (x<=l&&y>=r) return tr[i];
    113     else {
    114        int m=(l+r)>>1; ll s=0;
    115        if (laz[i]) push(i,l,r);
    116        if (x<=m) s+=ask(i*2,l,m,x,y);
    117        if (y>m) s+=ask(i*2+1,m+1,r,x,y);
    118        return s;
    119     }
    120 }
    121 
    122 ll getans(int x)
    123 {
    124     ll s=0;
    125     while (x)
    126     {
    127         int y=top[x];
    128         if (!c[y]||d[c[y]]>d[x]) return s;
    129         s+=ask(1,1,n,l[c[y]],l[x]);
    130         if (c[y]!=y) {c[y]=nex[x]; return s;}
    131         c[y]=nex[x]; x=fa[y];
    132         if (!v[y])
    133         {
    134             q[++t]=y;
    135             v[y]=1;
    136         }
    137     }
    138     return s;
    139 }
    140 
    141 void clr()
    142 {
    143     for (int i=1; i<=t; i++)
    144     {
    145         int x=q[i];
    146         v[x]=0; c[x]=x;
    147     }
    148     t=0;
    149 }
    150 
    151 int main()
    152 {
    153     int cas;
    154     scanf("%d",&cas);
    155     while (cas--)
    156     {
    157         scanf("%d",&n);
    158         memset(go,0,sizeof(go));
    159         memset(f,0,sizeof(f));
    160         for (int i=2; i<=n; i++)
    161         {
    162             int x;
    163             scanf("%d%s",&x,&ss);
    164             go[x-1][ss[0]-'a']=i-1;
    165         }
    166         for (int i=1; i<=n; i++) g[i].clear();
    167         bfs(); t=0;
    168         dfs(1); top[1]=1; get(1);
    169         for (int i=1; i<=n; i++) c[i]=i;
    170         memset(tr,0,sizeof(tr));
    171         memset(laz,0,sizeof(laz));
    172         scanf("%d",&m); t=0;
    173         for (int i=1; i<=m; i++)
    174         {
    175             scanf("%d",&ch);
    176             scanf("%d",&k);
    177             for (int j=1; j<=k; j++) scanf("%d",&a[j]);
    178             if (ch==1)
    179             {
    180                 sort(a+1,a+1+k,cmp);
    181                 int b=l[a[1]],e=r[a[1]];
    182                 for (int j=2; j<=k; j++)
    183                 {
    184                     if (e<l[a[j]])
    185                     {
    186                         add(1,1,n,b,e);
    187                         b=l[a[j]];
    188                         e=r[a[j]];
    189                     }
    190                     else e=max(e,r[a[j]]);
    191                 }
    192                 add(1,1,n,b,e);
    193             }
    194             else {
    195                 ll ans=0;
    196                 for (int j=1; j<=k; j++) ans+=getans(a[j]);
    197                 clr();
    198                 printf("%lld
    ",ans);
    199             }
    200         }
    201     }
    202 }
    View Code
  • 相关阅读:
    初学Google Code,Subversion和TortoiseSVN
    成长,真有你想象的那样迫切?
    Java中十个常见的违规编码
    Eclipse打包工具Fatjar
    “旁观者效应”是如何毁掉我们的代码的
    java设计模式—分类
    java中的关键字static(静态变量)和final定义常量
    JAVA UDP打洞必备知识点NAT
    [Struts]在jsp里处理比较复杂的内容?
    反向链接referrer的原理
  • 原文地址:https://www.cnblogs.com/phile/p/6378531.html
Copyright © 2011-2022 走看看