• bzoj4003


    http://www.lydsy.com/JudgeOnline/problem.php?id=4003

    可合并堆。

    每个点都有一个小根堆,记住可以到这个点的骑士有哪些,以战斗力为关键字。

    从底层到顶层不断合并,然后不断取出战斗力的最小值,如果小于防御值,则去掉最小值。

    操作可以打标记。

    我用了左偏树。

    左偏树太不熟悉了,打错了2个地方,去了皮的大土豆~OTATO

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define fill(a,l,r,v) fill(a+l,a+r+1,v)
    #define re(i,a,b)  for(i=(a);i<=(b);i++)
    #define red(i,a,b) for(i=(a);i>=(b);i--)
    #define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define p_b(a) push_back(a)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxN=300000;
    
    int N,M;
    vector<int> son[maxN+100];
    vector<int> Q[maxN+100];
    int f[maxN+100],dep[maxN+100],a[maxN+100];
    LL h[maxN+100],v[maxN+100];
    int c[maxN+100];
    LL s[maxN+100];
    
    struct Tnode
      {
          Tnode *l,*r;
          LL v,mu,add;int id,dis;
          inline Tnode(LL _v=0,LL _mu=1,LL _add=0,int _id=0,int _dis=0){l=0;r=0;v=_v;mu=_mu;add=_add;id=_id;dis=_dis;}
          inline int ldis(){return l?l->dis:0;}
          inline int rdis(){return r?r->dis:0;}
          inline void down()
            {
                if(mu==1 && add==0)return;
                if(l)l->v=l->v*mu+add,l->add=mu*l->add+add,l->mu=mu*l->mu;
                if(r)r->v=r->v*mu+add,r->add=mu*r->add+add,r->mu=mu*r->mu;
                mu=1;add=0;
            }
      };
    
    inline Tnode  *uni(Tnode *a,Tnode *b)
      {
          if(!a)return b;
          if(!b)return a;
          a->down();
            b->down();
          if(a->v > b->v)swap(a,b);
          a->r=uni(a->r,b);
          if(a->ldis() < a->rdis())swap(a->l,a->r);
          a->dis=a->rdis()+1;
          return a;
      }
    
    Tnode mem[maxN+100];
    Tnode *rt[maxN+100];
    
    int ge[maxN+100],out[maxN+100];
    
    int main()
      {
          /*freopen("bzoj4003.in","r",stdin);
            freopen("bzoj4003.out","w",stdout);*/
            int i,j;
            N=gint();M=gint();
            re(i,1,N)h[i]=gll();
            re(i,2,N)f[i]=gll(),a[i]=gint(),v[i]=gll(),son[f[i]].p_b(i);
            re(i,1,M)s[i]=gll(),c[i]=gint(),Q[c[i]].p_b(i);
            re(i,1,N)dep[i]=dep[f[i]]+1;
            re(i,1,M)mem[i]=Tnode(s[i],1,0,i,1);
            red(i,N,1)
              {
                  re(j,0,int(son[i].size())-1)
                      {
                          int ch=son[i][j];
                            rt[i]=uni(rt[i],rt[ch]);
                        }
                    re(j,0,int(Q[i].size())-1)
                      {
                          int t=Q[i][j];
                          rt[i]=uni(rt[i],&mem[t]);
                      }
                    while(rt[i] && rt[i]->v<h[i])
                      {
                          ge[i]++;
                          int t=rt[i]->id;
                          out[t]=dep[c[t]]-dep[i];
                          rt[i]->down();////////////////////////////////////////////注意这里要down
                          rt[i]=uni(rt[i]->l,rt[i]->r);
                      }
                    if(rt[i])
                      if(a[i]==0)
                        rt[i]->v+=v[i],rt[i]->add+=v[i];
                      else
                        rt[i]->v*=v[i],rt[i]->mu*=v[i],rt[i]->add*=v[i];
                }
            while(rt[1])
              {
                  int t=rt[1]->id;
                  out[t]=dep[c[t]];
                  rt[1]->down();////////////////////////////////////////////注意这里要down
                  rt[1]=uni(rt[1]->l,rt[1]->r);
              }
            re(i,1,N)PF("%d
    ",ge[i]);
            re(i,1,M)PF("%d
    ",out[i]);
            return 0;
      }
    View Code

    然后有另外一种不适用这题的方法。

    我们发现,如果某个骑士的初始战斗力为x,那么骑士在当前点的战斗力为ax+b,其实a和b只跟出发点和当前点的位置有关,与x无关。

    并且我们发现a一定是正数。

    类似于LCA,

    to[i][j]表示i号点跳2^j次到的点。

    jump[i][j]表示,这是一个pair,表示一个初始位置在i号点的骑士的初始战斗力为x,跳2^j次后,战斗力变成jump[i][j].fi*x+jump[i][j].se,其实jump[i][j].fi和jump[i][j].se只和i,有关,与x无关。

    minx[i][j]表示,一个初始位置在i号点的骑士的初始战斗力为x,想要跳2^j次,x至少要为minx[i][j]。

    容易发现x[i][j]随着j的递增而递增,有单调性。

    可以用nlogn的时间求出。

    然后对于初始位置在i的骑士,记其初始战斗力为x,二分j,判断x与minx[i][j]的大小关系即可。

    但是这道题不适用的地方在于:

    (1)MLE

    (2)题目保证“任何时候骑士战斗力值的绝对值不超过 10^18”,不是"骑士跑到到根战斗力值的绝对值不超过 10^18“,这样很容易就爆longlong了。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<LL,LL> PLL;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define fill(a,l,r,v) fill(a+l,a+r+1,v)
    #define re(i,a,b)  for(i=(a);i<=(b);i++)
    #define red(i,a,b) for(i=(a);i>=(b);i--)
    #define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    const DB EPS=1e-9;
    inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    inline int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    inline LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
      }
    
    const int maxN=300000;
    const LL INF=(1LL<<63)-1;
    
    int N,M;
    LL s[maxN+100];int c[maxN+100];
    int f[maxN+100],a[maxN+100];
    LL h[maxN+100],v[maxN+100];
    
    int dep[maxN+100];
    int to[maxN+100][20];
    PLL jump[maxN+100][20];
    LL minx[maxN+100][20];
    
    int g[maxN+100],out[maxN+100];
    
    int main()
      {
          freopen("bzoj4003.in","r",stdin);
          freopen("bzoj4003.out","w",stdout);
          int i,j;
          N=gint();M=gint();
          re(i,1,N)h[i]=gll();
          re(i,2,N)f[i]=gint(),a[i]=gint(),v[i]=gll();
          re(i,1,M)s[i]=gll(),c[i]=gint();
          
          dep[1]=1;
          re(j,0,19)to[1][j]=1;
          re(j,0,19)jump[1][j]=PLL(1,0);
          re(j,0,19)minx[1][j]=INF;
          re(i,2,N)
            {
                dep[i]=dep[f[i]]+1;
                to[i][0]=f[i];
                re(j,1,19)to[i][j]=to[to[i][j-1]][j-1];
                if(a[i]==0) jump[i][0]=PLL(1,v[i]); else jump[i][0]=PLL(v[i],0);
                re(j,1,19)
                  {
                      LL da=jump[i][j-1].fi,db=jump[i][j-1].se,a=jump[to[i][j-1]][j-1].fi,b=jump[to[i][j-1]][j-1].se;
                      jump[i][j]=PLL(a*da,a*db+b);
                  }
                minx[i][0]=h[i];
                re(j,1,19)
                  {
                      minx[i][j]=minx[i][j-1];
                      LL a=jump[i][j-1].fi,b=jump[i][j-1].se,temp=minx[to[i][j-1]][j-1];
                      if(temp==INF) upmax(minx[i][j],INF); else upmax(minx[i][j],(temp-b-1)/a+1);
                  }
            }
          
          re(i,1,M)
            {
                int p=c[i];LL x=s[i];
                red(j,19,0)
                      if(x>=minx[p][j])
                        {
                            x=x*jump[p][j].fi+jump[p][j].se;
                                p=to[p][j];
                            }
                    if(x<h[p])g[p]++;
                    out[i]=dep[c[i]]-dep[p];if(x>=h[p])out[i]++;
                }
            
            re(i,1,N)PF("%d
    ",g[i]);
            re(i,1,M)PF("%d
    ",out[i]);
            
          return 0;
      }
    View Code
  • 相关阅读:
    Tomcat下HTTPS双向认证配置以及客户端调用案例
    Java本地运行中文正常,部署到Weblogic中文乱码
    gson 忽略掉某些字段不进行转换
    JavaScript中定义对象的四种方式
    使用CSS3实现超炫的Loading(加载)动画效果
    不要再使用JS框架了
    HTML5, CSS3, ES5新的web标准和浏览器支持一览 转
    js常用的事件对象
    jQuery用面向对象的思想来编写验证表单的插件
    五个值得尝试的前端开发工具
  • 原文地址:https://www.cnblogs.com/maijing/p/4754018.html
Copyright © 2020-2023  润新知