zoukankan      html  css  js  c++  java
  • BZOJ5507 GXOI/GZOI2019旧词 (树链剖分+线段树)

      https://www.cnblogs.com/Gloid/p/9412357.html差分一下是一样的问题。感觉几年没写过树剖了。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 50010
    #define P 998244353
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,q,k,fa[N],p[N],w[N],ans[N],t;
    int dfn[N],id[N],size[N],deep[N],top[N],son[N],cnt;
    int tree[N<<2],lazy[N<<2],L[N<<2],R[N<<2],s[N<<2];
    struct data{int to,nxt;
    }edge[N];
    struct data2
    {
    	int x,y,i;
    	bool operator <(const data2&a) const
    	{
    		return x<a.x; 
    	}
    }Q[N];
    void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
    int ksm(int a,int k)
    {
    	int s=1;
    	for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
    	return s; 
    }
    void dfs1(int k)
    {
    	size[k]=1;
    	for (int i=p[k];i;i=edge[i].nxt)
    	{
    		deep[edge[i].to]=deep[k]+1;
    		dfs1(edge[i].to);
    		size[k]+=size[edge[i].to];
    		if (size[edge[i].to]>size[son[k]]) son[k]=edge[i].to;
    	}
    }
    void dfs2(int k,int from)
    {
    	dfn[k]=++cnt;id[cnt]=k;top[k]=from;
    	if (son[k]) dfs2(son[k],from);
    	for (int i=p[k];i;i=edge[i].nxt)
    	if (edge[i].to!=son[k]) dfs2(edge[i].to,edge[i].to);
    }
    void build(int k,int l,int r)
    {
    	L[k]=l,R[k]=r;
    	if (l==r) {s[k]=w[deep[id[l]]];return;}
    	int mid=l+r>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    	s[k]=(s[k<<1]+s[k<<1|1])%P;
    }
    void update(int k,int x)
    {
    	lazy[k]+=x;
    	tree[k]=(tree[k]+1ll*x*s[k])%P;
    }
    void down(int k)
    {
    	update(k<<1,lazy[k]);
    	update(k<<1|1,lazy[k]);
    	lazy[k]=0;
    }
    void add(int k,int l,int r)
    {
    	if (L[k]==l&&R[k]==r) {update(k,1);return;}
    	if (lazy[k]) down(k);
    	int mid=L[k]+R[k]>>1;
    	if (r<=mid) add(k<<1,l,r);
    	else if (l>mid) add(k<<1|1,l,r);
    	else add(k<<1,l,mid),add(k<<1|1,mid+1,r);
    	tree[k]=(tree[k<<1]+tree[k<<1|1])%P;
    }
    int query(int k,int l,int r)
    {
    	if (L[k]==l&&R[k]==r) return tree[k];
    	if (lazy[k]) down(k);
    	int mid=L[k]+R[k]>>1;
    	if (r<=mid) return query(k<<1,l,r);
    	else if (l>mid) return query(k<<1|1,l,r);
    	else return (query(k<<1,l,mid)+query(k<<1|1,mid+1,r))%P;
    }
    void ins(int x)
    {
    	while (x)
    	{
    		add(1,dfn[top[x]],dfn[x]);
    		x=fa[top[x]];
    	}
    }
    int get(int x)
    {
    	int s=0;
    	while (x)
    	{
    		s=(s+query(1,dfn[top[x]],dfn[x]))%P;
    		x=fa[top[x]];
    	}
    	return s;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("bzoj5507.in","r",stdin);
    	freopen("bzoj5507.out","w",stdout);
    	const char LL[]="%I64d
    ";
    #else
    	const char LL[]="%lld
    ";
    #endif
    	n=read(),q=read(),k=read();
    	for (int i=2;i<=n;i++)
    	{
    		fa[i]=read();
    		addedge(fa[i],i);
    	}
    	for (int i=0;i<=n;i++) w[i]=ksm(i,k);
    	for (int i=n;i>=1;i--) w[i]=(w[i]-w[i-1]+P)%P;
    	deep[1]=1;dfs1(1);dfs2(1,1);
    	build(1,1,n);
    	for (int i=1;i<=q;i++) Q[i].x=read(),Q[i].y=read(),Q[i].i=i;
    	sort(Q+1,Q+q+1);
    	int cur=0;
    	for (int i=1;i<=q;i++)
    	{
    		while (cur<Q[i].x) ins(++cur);
    		ans[Q[i].i]=get(Q[i].y);
    	}
    	for (int i=1;i<=q;i++) printf("%d
    ",ans[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    JavaScript-循环
    JavaScript-条件判断
    JavaScript-对象
    Vue快速入门
    Typora中的MarkDown语法
    (已解决)ERROR: In file './docker-compose.yml', service 'networks' must be a mapping not an array
    mac常用快捷键
    Python数据分析
    Python列表和元组
    Selenium工具爬取商品
  • 原文地址:https://www.cnblogs.com/Gloid/p/10726366.html
Copyright © 2011-2022 走看看