zoukankan      html  css  js  c++  java
  • 【洛谷5362】[SDOI2019] 连续子序列(找规律)

    点此看题面

    • 有一个(01)序列(T),满足(T_0=0,T_{2n}=T_n,T_{2n+1}=T_noplus1)
    • 给定一个(01)(S)和一个常数(k),求有多少字符串,满足它是在(S)后面加上(k)个字符得到的,且在(T)中出现过。
    • 数据组数(le100)(|S|le100,kle10^{18})

    找规律+记忆化搜索

    说实话我是先在NOI Online #4的(T1)中遭遇大失败之后才来做这道题的,然而依旧是大失败。

    这个(01)(T)有非常多的性质,这里就不一一列举了,只给出这道题中需要的关键性质:

    如果我们每次将这个(01)串长度倍增,那么相当于每个(0)会变成(01),每个(1)会变成(10)

    利用这个性质,这道题我们只需要做逆变换,把(S)给缩回去即可。

    具体地,对于当前串(S),它只有两种可能的来源:从第一个字符开始每两个一组,从第二个字符开始每两个一组。

    注意,一组的两个字符必须不同,也正因此两侧的单个字符其实也可以唯一确定与其配对的字符。

    然后就直接记搜一遍即可,因为一次搜索尽管会产生两个状态,但(S)的长度也相应减半了,所以总状态数不大,复杂度是正确的。

    注意,当(S)长度和(k)都很小的时候需要判一下边界,否则会挂掉。比较良心的是,需要判的边界在样例中都有涉及,因此只要过了样例基本上就没问题了。(做的时候我还思考为什么每个样例都要特判,还怀疑自己想法是不是错了。。。)

    代码:(O(T(|S|+logk)))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100
    #define LL long long
    #define X 1000000009
    using namespace std;
    string s;LL k;
    map<pair<string,LL>,int> f;I int DP(string s,Con LL& k)
    {
    	if(f.count(make_pair(s,k))) return f[make_pair(s,k)];//记忆化搜索
    	RI l=s.length();if(l==1&&k<=2) return k+1;//l=1且k很小的边界状态
    	if(l==2&&k<=1) return 1+(k&&s[0]^s[1]);if(l==3&&!k) return s[0]^s[1]||s[1]^s[2];//l=2或3且k很小的边界状态
    	RI i,p,t=0;string ns;for(p=0;p<=1;++p)//两种划分
    	{
    		for(p&&((ns="0")[0]=s[0]^1),i=p;i+1<l&&s[i]^s[i+1];i+=2) ns+=s[i];//确定左侧单字符,中间两两配对字符必须不同
    		i+1>=l&&(i==l-1&&(ns+=s[l-1],0),t=(t+DP(ns,k+!(l&1^p)>>1))%X);//确定右侧单字符,递归
    	}return f[make_pair(s,k)]=t;
    }
    int main()
    {
    	ios::sync_with_stdio(false);RI Tt;cin>>Tt;W(Tt--) cin>>s>>k,cout<<DP(s,k)<<endl;return 0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    PHP 使用 GET 传递数组变量
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu5362.html
Copyright © 2011-2022 走看看