【LOJ2252】「ZJOI2017」多项式

【题目链接】

【思路要点】

  • 2 2 2 意义下,多项式平方相等于将每一项的指数翻倍。
  • 我们需要维护一些关于字符串 S S S 的信息,使得其能够进行 “指数翻倍” 和 “指数翻倍并乘以原多项式” 的操作。
  • 首先考虑测试点 6 , 7 , 8 6,7,8 6,7,8
  • 考虑维护字符串 S S S ∣ S ∣ − 17 |S|-17 S17 个长度为 18 18 18 的字符串中,每一种字符串的个数,以及 S S S 开头和结尾至多 50 50 50 个字符。
  • “指数翻倍” 时,每一个长度为 18 18 18 的字符串将变为一个长度为 2 × 18 + 1 2\times18+1 2×18+1 的字符串,这里 + 1 +1 +1 是由于算上了两侧的 0 0 0 ,取最后两个长度为 18 18 18 的子串作为得到的新结果,并利用开头的若干字符更新边界上新产生的子串。
  • “指数翻倍并乘以原多项式” 时,原多项式是一个次数最高为 18 18 18 的多项式,每一个长度为 18 18 18 的字符串 “指数翻倍” 后长度为 37 37 37 ,相乘后恰好最后两个长度为 18 18 18 的子串是准确的,而剩余长度为 18 18 18 的子串均包含了不能仅根据 “指数翻倍” 后的字符串计算的位置。依然取取最后两个长度为 18 18 18 的子串作为得到的新结果,并利用开头和结尾的若干字符更新边界上新产生的子串。
  • 对于其余测试点,我们需要支持对前缀信息的询问,可以直接在每次倍增后删除掉字符串尾的若干字符做到,因此开头和结尾需要记录至少 2 N + c 2N+c 2N+c 个字符。
  • 时间复杂度 O ( 2 max ⁡ ( n , k ) × ( N + L o g M ) + N L o g M ) O(2^{\max(n,k)}\times (N+LogM)+NLogM) O(2max(n,k)×(N+LogM)+NLogM)

【代码】

#include<bits/stdc++.h>
using namespace std;
const int N = 17, M = 50, goal = (1 << 18) - 1;
const int MAXN = 25, MAXLOG = 62;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值