zoukankan      html  css  js  c++  java
  • bzoj 5123: [Lydsy1712月赛]线段树的匹配

        设f[0/1][x]为区间[1,x]的根向下 不选(0)或者选(1)  的dp pair<最优值,方案数>。

        可以很容易的发现总状态数就是log级别的,因为2*n 与 (2*n+1 或者 2*n-1) 向下有很多重叠,记忆化搜索即可。

       

        初始化的话 f[0][1] = {0,1}, f[1][1] = {0,0} ,切记后者的方案数不能为1,不仅与事实不符,也会与前者重叠。

    #include<bits/stdc++.h>
    #include<tr1/unordered_map>
    using namespace std;
    using namespace std::tr1;
    #define ll long long
    const int ha=998244353;
    inline void ADD(int &x,int y){ x+=y; if(x>=ha) x-=ha;}
    struct node{
    	ll M; int S;
    	node operator +(const node &u)const{
    		node r=u;
    		if(M>r.M) r=*this;
    		else if(M==r.M) ADD(r.S,S);
    		return r;
    	}
    	node operator *(const node &u)const{
    		return (node){M+u.M,S*(ll)u.S%ha};
    	}
    }A,B;
    unordered_map<ll,node> f[2];
    
    void dp(ll x){
    	if(f[0].count(x)) return;
    	ll mid=x>>1;
    	dp(mid),dp(x-mid);
    	
    	f[0][x]=(f[0][mid]+f[1][mid])*(f[0][x-mid]+f[1][x-mid]);
    	f[1][x]=f[0][mid]*f[1][x-mid]*A+f[1][mid]*f[0][x-mid]*A+f[0][mid]*f[0][x-mid]*B;
    }
    
    int main(){
    	f[0][1]=(node){0,1},f[1][1]=(node){0,0};
    	A=(node){1,1},B=(node){1,2};
    	ll n; scanf("%lld",&n),dp(n);
    	node ans=f[0][n]+f[1][n];
    	printf("%lld %d
    ",ans.M,ans.S);
    	return 0;
    }
    

      

  • 相关阅读:
    2018_10_15 堆栈内存
    2018_10_14 java 环境 win10
    2018_09_21 ftp 安装
    2018_09_21 myeclipse git插件
    转 iOS开发中一些常见的并行处理
    转【iOS设计】一款APP从设计稿到切图过程概述
    算法题
    iOS -copy-mutableCopy- NSHashTable -NSMapTable-Keychain
    转--iOS下JS与原生OC互相调用
    ReactiveCocoa
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8939673.html
Copyright © 2011-2022 走看看