zoukankan      html  css  js  c++  java
  • Gym101620C Cumulative Code

    Link
    记忆化搜索。
    将搜索的状态设为((n,k,now,flg)),表示深度为(n),已有(k)位Prüfer Code,剩余(now)个需要被计算的位置,是否有父边。
    假如当前的点为(x),那么我们将答案打成一个三元的结构体((a,b,c)),表示答案为(ax+b+clfloorfrac x2 floor)
    设当前点的答案为((a,b,c)),儿子的答案为((A,B,C)),考虑如何合并。
    左儿子:(aleftarrow a+2A+C,bleftarrow b+B)
    右儿子:(aleftarrow a+2A+C,bleftarrow b+A+B)
    然后考虑利用记忆化优化时间复杂度。
    首先只有当该子树对应的Prüfer Code编号在([a,a+(m−1)d]),且该子树有父边才进行记忆化。
    我们设记忆的状态为(f_{k,i})表示根节点为(x),深度为(k),且任意(p′_{i+jd})都是需要被计算答案的点的答案为(f_{k,i})结构体所表示的答案((P'={p'_n})为子树的Prüfer Code)。
    因为所有有父边深度为(k)的满二叉树的删除顺序是一定的,所以这一部分的答案只与该子树Prüfer Code中第一个被选取的点的offset有关。
    我们只记录(kle 15)的状态,这样单次搜索的时间复杂度为(2^{frac k2})

    #include<cstdio>
    #include<algorithm>
    using i64=long long;
    int read(){int x;scanf("%d",&x);return x;}
    const int N=17,M=32768;
    struct node
    {
        i64 a,b,c;
        node(i64 A=0,i64 B=0,i64 C=0):a(A),b(B),c(C){};
        void mergel(node x){a+=x.a+x.a+x.c,b+=x.b;}
        void merger(node x){a+=x.a+x.a+x.c,b+=x.a+x.b;}
    }f[N][M];
    int st,d,m,ed,num,id[N][M];
    node dfs(int n,int k,int now,int flg)
    {
        if(now<=0) return node();
        int p=((st-k)%d+d)%d,size,pos;node ans;
        if(!p) p=d;
        p=std::max(p,st-k);
        if(p>=1<<n) return node();
        if(n<=1) return node(0,0,1);
        if(n<=15&&flg&&k+1>=st&&k+(1<<n)-1<=ed&&id[n][p]==num) return f[n][p];
        if(p<=(1<<(n-1))-1) size=(std::min(ed-k,(1<<(n-1))-1)-p)/d+1,ans.mergel(dfs(n-1,k,size,1)),now-=size;
        if(!flg) if(pos=k+(1<<(n-1)),!((pos-st)%d)&&st<=pos&&pos<=ed) ans.a+=2,++ans.b,--now;
        if(now>0) pos=k+(1<<n)-1,ans.merger(dfs(n-1,k+(1<<(n-1))-flg,now-(flg&&!((pos-st)%d)&&st<=pos&&pos<=ed),flg));
        if(flg) if(pos=k+(1<<n)-1,!((pos-st)%d)&&st<=pos&&pos<=ed) ++ans.c;
        if(n<=15&&flg&&k+1>=st&&k+(1<<n)-1<=ed) id[n][p]=num,f[n][p]=ans;
        return ans;
    }
    
    int main()
    {
        for(int dep=read(),Q=read();Q;--Q)
        {
    	++num,st=read(),d=read(),m=read(),ed=st+d*(m-1);
    	node ans=dfs(dep,0,m,0);printf("%lld
    ",ans.a+ans.b);
        }
    }
    
  • 相关阅读:
    STM32下载程序后不能运行
    (转载)时序约束的基本方法
    PLL失锁的问题
    算法与硬件构架的关系
    构建低成本、高度可配置的桥接解决方案:在嵌入式设计中采用基于D-PHY的MIPI标准外设
    SOLDERMASK_TOP不显示
    Allegro brd文件更新封装及焊盘方法
    Cadence Allegro光绘文件生成技巧
    shape合并
    allegro 如何 敷铜(铺铜),并去掉敷铜岛
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12602811.html
Copyright © 2011-2022 走看看