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

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

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

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

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

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

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

 #include<bits/stdc++.h>

 using namespace std;
typedef long long ll;
int go[][],a[],fa[],laz[],l[],r[],c[],q[],s[],nex[],top[],f[],d[];
int n,m,k,t,ch;
vector<int> g[];
bool v[];
ll tr[];
char ss[]; bool cmp(int a,int b)
{
if (l[a]==l[b]) return r[a]<r[b];
return l[a]<l[b];
} void bfs()
{
int h=,r=;
for (int i=; i<; i++)
if (go[][i])
{
g[].push_back(go[][i]+);
q[++r]=go[][i];
}
while (h<=r)
{
int x=q[h++];
for (int i=; i<; i++)
if (go[x][i])
{
int y=go[x][i];
q[++r]=y;
int j=f[x];
while (j>&&!go[j][i]) j=f[j];
f[y]=go[j][i];
g[go[j][i]+].push_back(y+);
}
}
} void dfs(int x)
{
s[x]=;
for (int i=; i<g[x].size(); i++)
{
int y=g[x][i];
// cout <<x<<" "<<y<<endl;
d[y]=d[x]+;
fa[y]=x;
dfs(y);
s[x]+=s[x];
}
} void get(int x)
{
l[x]=++t;
int q=;
for (int i=; i<g[x].size(); i++)
{
int y=g[x][i];
if (s[y]>s[q]) q=y;
}
if (q)
{
top[q]=top[x];
get(q);
}
nex[x]=q;
for (int i=; i<g[x].size(); i++)
{
int y=g[x][i];
if (y!=q)
{
top[y]=y;
get(y);
}
}
r[x]=t;
} void push(int i,int l,int r)
{
int m=(l+r)>>;
tr[i*]+=1ll*laz[i]*(m+-l);
tr[i*+]+=1ll*laz[i]*(r-m);
laz[i*]+=laz[i];
laz[i*+]+=laz[i];
laz[i]=;
} void add(int i,int l,int r,int x,int y)
{
if (x<=l&&y>=r)
{
tr[i]+=(r-l+);
laz[i]++;
}
else {
int m=(l+r)>>;
if (laz[i]) push(i,l,r);
if (x<=m) add(i*,l,m,x,y);
if (y>m) add(i*+,m+,r,x,y);
tr[i]=tr[i*]+tr[i*+];
}
} ll ask(int i,int l,int r,int x,int y)
{
if (x<=l&&y>=r) return tr[i];
else {
int m=(l+r)>>; ll s=;
if (laz[i]) push(i,l,r);
if (x<=m) s+=ask(i*,l,m,x,y);
if (y>m) s+=ask(i*+,m+,r,x,y);
return s;
}
} ll getans(int x)
{
ll s=;
while (x)
{
int y=top[x];
if (!c[y]||d[c[y]]>d[x]) return s;
s+=ask(,,n,l[c[y]],l[x]);
if (c[y]!=y) {c[y]=nex[x]; return s;}
c[y]=nex[x]; x=fa[y];
if (!v[y])
{
q[++t]=y;
v[y]=;
}
}
return s;
} void clr()
{
for (int i=; i<=t; i++)
{
int x=q[i];
v[x]=; c[x]=x;
}
t=;
} int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d",&n);
memset(go,,sizeof(go));
memset(f,,sizeof(f));
for (int i=; i<=n; i++)
{
int x;
scanf("%d%s",&x,&ss);
go[x-][ss[]-'a']=i-;
}
for (int i=; i<=n; i++) g[i].clear();
bfs(); t=;
dfs(); top[]=; get();
for (int i=; i<=n; i++) c[i]=i;
memset(tr,,sizeof(tr));
memset(laz,,sizeof(laz));
scanf("%d",&m); t=;
for (int i=; i<=m; i++)
{
scanf("%d",&ch);
scanf("%d",&k);
for (int j=; j<=k; j++) scanf("%d",&a[j]);
if (ch==)
{
sort(a+,a++k,cmp);
int b=l[a[]],e=r[a[]];
for (int j=; j<=k; j++)
{
if (e<l[a[j]])
{
add(,,n,b,e);
b=l[a[j]];
e=r[a[j]];
}
else e=max(e,r[a[j]]);
}
add(,,n,b,e);
}
else {
ll ans=;
for (int j=; j<=k; j++) ans+=getans(a[j]);
clr();
printf("%lld\n",ans);
}
}
}
}

hdu5081的更多相关文章

随机推荐

  1. Struts1之logic标签

    logic是Struts1中的逻辑标签 <%@ taglib prefix="logic" uri="http://struts.apache.org/tags-l ...

  2. 微服务日志监控与查询logstash + kafka + elasticsearch

    使用 logstash + kafka + elasticsearch 实现日志监控 https://blog.csdn.net/github_39939645/article/details/788 ...

  3. Spark分布式执行原理

    Spark分布式执行原理 让代码分布式运行是所有分布式计算框架需要解决的最基本的问题. Spark是大数据领域中相当火热的计算框架,在大数据分析领域有一统江湖的趋势,网上对于Spark源码分析的文章有 ...

  4. 【CF edu 30 D. Merge Sort】

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  5. Unescape JavaScript's escape() using C#

    js里面的 unescape escape 对应C#里面 var unescapedString = Microsoft.JScript.GlobalObject.unescape(yourEscap ...

  6. [NOI2002] 银河英雄传说 (带权并查集)

    题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...

  7. [hdu 6069]素数筛+区间质因数分解

    给[L,R]区间的每一个数都质因数分解的复杂度可以达到(R-L)logR,真的涨姿势…… 另外,质因数分解有很重要的一点,就是只需要打sqrt(R)以内的素数表就够了……因为超过sqrt(R)的至多只 ...

  8. struts2学习问题(一)

    一.struts2 Unknown tag (s:property). 解释:不识别标签 解决:这是sturts2的标签,导入相应的包<%@taglib prefix="s" ...

  9. rpmdb open failed解决方案

    1.前提条件:安装软件包的时候,被我手动终止了(可能出错原因)[root@dhcp yum.repos.d]# yum clean allrpmdb: Thread/process 4541/1406 ...

  10. bzoj3382 [Usaco2004 Open]Cave Cows 3 洞穴里的牛之三

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3382 [题解] 套路题. 首先我们会发现曼哈顿距离不好处理,难道要写kdtree??? (k ...