【BZOJ4003】【JLOI2015】城池攻占 可并堆

来源:互联网 发布:下载枪林弹雨刷枪软件 编辑:程序博客网 时间:2024/05/17 03:58

链接:

#include <stdio.h>int main(){    puts("转载请注明出处[vmurder]谢谢");    puts("网址:blog.csdn.net/vmurder/article/details/45170045");}

题解:

傻题随便上数据结构都能搞过。
可并堆或者启发式合并splay都可以。
考试时状态太差一个裸模板启发式合并splay调了3h最后还爆零了Qwq、

200行!!!!!!
然后可并堆又快又短,细节又少(然后特么也全都是模板内容,一点非模板代码都没有……),完虐启发式合并。

另外这道题可以用 f(i,j) 表示 从点 i 到其第 2j 个父亲需要的最小战斗力,这种做法虽然会被卡精度,但是数据没有去卡它,是能过的。
但是这种做法貌似内存爆了一倍?

还有就是这道题本来是一个点10s,然后bzoj总时限10s,有点卡。
启发式合并splay就扔了吧,它虽然也是一个log,但是是均摊,而且还有大常数,估计多半会TLE。

代码:

#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 301000#define ls son[x][0]#define rs son[x][1]#define inf 0x3f3f3f3f#define INF 0x3f3f3f3f3f3f3f3fll#define check {puts("!!!");exit(0);}using namespace std;bool ai[N];int murders[N],fa[N];long long hi[N],vi[N];int ans[N],n,m;struct Merge_Heap{    int son[N][2],root[N],id[N],cnt;    long long val[N],ad[N],mu[N];    int level[N],exper[N];    void pushdown(int x)    {        if(mu[x]!=1)        {            val[x]*=mu[x];            mu[ls]*=mu[x],mu[rs]*=mu[x];            ad[ls]*=mu[x],ad[rs]*=mu[x];            mu[x]=1;        }        if(ad[x])        {            val[x]+=ad[x];            ad[ls]+=ad[x],ad[rs]+=ad[x];            ad[x]=0;        }        if(exper[x])        {            level[x]+=exper[x];            exper[ls]+=exper[x],exper[rs]+=exper[x];            exper[x]=0;        }    }    int merge(int x,int y)    {        if(!y)return x;        if(!x)return y;        pushdown(x),pushdown(y);        if(val[x]>val[y])swap(x,y);        int d=rand()&1;        son[x][d]=merge(son[x][d],y);        return x;    }    int newnode(long long _val,int _id)    {        val[++cnt]=_val;        id[cnt]=_id;        mu[cnt]=1;        return cnt;    }    void add(int p,long long val,int id)    {root[p]=merge(root[p],newnode(val,id));}    void kill(int p)    {        for(int x=root[p];x;x=root[p])        {            pushdown(x);            if(val[x]>=hi[p])return ;            ans[id[x]]=level[x];            murders[p]++;            root[p]=merge(ls,rs);        }    }    void hold(int p)    {        pushdown(root[p]);        if(ai[p])mu[root[p]]=vi[p];        else ad[root[p]]=vi[p];        exper[root[p]]++;        root[fa[p]]=merge(root[fa[p]],root[p]);    }}mh;int d[N],stk[N],top;int main(){    int i,j,k;    int a,b,c;    long long t;    scanf("%d%d",&n,&m);    for(i=1;i<=n;i++)scanf("%lld",&hi[i]);    for(i=2;i<=n;i++)scanf("%d%d%lld",&fa[i],&ai[i],&vi[i]),d[fa[i]]++;    for(i=1;i<=m;i++)    {        scanf("%lld%d",&t,&a);        mh.add(a,t,i);    }    d[0]=1,hi[0]=INF;    for(i=1;i<=n;i++)if(!d[i])stk[++top]=i;    while(top)    {        k=stk[top--];        mh.kill(k);        if(k)        {            mh.hold(k);            d[fa[k]]--;            if(!d[fa[k]])stk[++top]=fa[k];        }    }    for(i=1;i<=n;i++)printf("%d\n",murders[i]);    for(i=1;i<m;i++)printf("%d\n",ans[i]);printf("%d",ans[m]);    return 0;}
1 1
原创粉丝点击