zoukankan      html  css  js  c++  java
  • bzoj 4372 烁烁的游戏——动态点分治+树状数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4372

    和 bzoj 3070 震波 是一个套路。注意区间修改的话,树状数组不能表示 dis = 0 的位置,所以要手动改父亲的点权数组。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #define ll long long
    using namespace std;
    const int N=1e5+5,K=20;
    int n,w[N],hd[N],xnt,to[N<<1],nxt[N<<1],siz[N],rt,mn;
    int pre[N][K],dep[N],dis[N][K],fs[N],gs[N]; vector<ll> f[N],g[N];
    bool vis[N];
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    int Mx(int a,int b){return a>b?a:b;}
    int Mn(int a,int b){return a<b?a:b;}
    void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
    void add(int cr,int x,int k){for(x=Mn(x,fs[cr]);x;x-=(x&-x))f[cr][x]+=k;}
    ll qry(int cr,int x){ll ret=0;for(;x&&x<=fs[cr];x+=(x&-x))ret+=f[cr][x];return ret;}
    void addx(int cr,int x,int k){for(x=Mn(x,gs[cr]);x;x-=(x&-x))g[cr][x]+=k;}
    ll qryx(int cr,int x){ll ret=0;for(;x&&x<=gs[cr];x+=(x&-x))ret+=g[cr][x];return ret;}
    void getrt(int cr,int fa,int s)
    {
      siz[cr]=1;int mx=0;
      for(int i=hd[cr],v;i;i=nxt[i])
        if(!vis[v=to[i]]&&v!=fa)
          {
        getrt(v,cr,s);siz[cr]+=siz[v];mx=Mx(mx,siz[v]);
          }
      mx=Mx(mx,s-siz[cr]); if(mx<mn)mn=mx,rt=cr;
    }
    void dfs(int cr,int fa,int ds)
    {
      pre[cr][++dep[cr]]=rt;dis[cr][dep[cr]]=ds;
      for(int i=hd[cr],v;i;i=nxt[i])
        if(!vis[v=to[i]]&&v!=fa)dfs(v,cr,ds+1);
    }
    void init(int cr,int s)
    {
      vis[cr]=1;fs[cr]=mn;gs[cr]=(mn<<1)+1;
      f[cr].resize(fs[cr]+1);g[cr].resize(gs[cr]+1);
      dfs(cr,0,0);
      for(int i=hd[cr],v;i;i=nxt[i])
        if(!vis[v=to[i]])
          {
        int ts=(siz[v]<siz[cr]?siz[v]:s-siz[cr]);
        mn=N;getrt(v,cr,ts);init(rt,ts);
          }
    }
    void mdfy(int cr,int d,int k)
    {
      add(cr,d,k); w[cr]+=k;
      for(int i=dep[cr]-1;i;i--)
        {
          if(dis[cr][i]>d)continue;
          add(pre[cr][i],d-dis[cr][i],k); w[pre[cr][i]]+=k;/////
          addx(pre[cr][i+1],d-dis[cr][i],k);
        }
    }
    ll query(int cr)
    {
      ll ret=w[cr];
      for(int i=dep[cr]-1;i;i--)
        {
          ret+=qry(pre[cr][i],dis[cr][i]);
          ret-=qryx(pre[cr][i+1],dis[cr][i]);
        }
      return ret;
    }
    int main()
    {
      n=rdn(); int Q=rdn();
      for(int i=1,u,v;i<n;i++)
        u=rdn(),v=rdn(),add(u,v),add(v,u);
      mn=N;getrt(1,0,n);init(rt,n);
      int x,d,k;char ch[5];
      while(Q--)
        {
          scanf("%s",ch);x=rdn();
          if(ch[0]=='Q')printf("%lld
    ",query(x));
          else
        {
          d=rdn(); k=rdn(); mdfy(x,d,k);
        }
        }
      return 0;
    }
  • 相关阅读:
    Sublime Text 命令大全(积累所得)
    端口号
    帝之意志 看透世间
    Session and Cookie的基础用法
    厌胜术
    微信支付
    微信登录
    navicat常用快捷键与SQL基本使用
    idea Spring项目一直报错,但是点击进去就恢复正常了,解决办法,通过mvn idea:module命令生成iml文件
    解决报错WARNING: IPv4 forwarding is disabled. Networking will not work.
  • 原文地址:https://www.cnblogs.com/Narh/p/10187308.html
Copyright © 2011-2022 走看看