AtCoder Regular Contest 099 題解
阿新 • • 發佈:2018-12-12
題意:
給出一個操作序列包含,分別是下標左移右移,當前位置加減。問有多少對滿足只做這裡面的操作,結果和做完所有操作一樣。
題解:
很神奇的一道題。 首先將操作後得到的序列看成一個多項式: 考慮在操作序列前加操作,多項式會變成什麼
給整個多項式一個hash值c,那麼就是問多少對滿足這樣得出來的序列的hash等於c。 這四個操作顯然是可逆的,設中的操作為逆操作為
變成兩個字尾形式,可以線性求出hash值,map統計即可。
自己寫的怎麼都過不了,各種hash被卡,抄了別人寫法
WA:
#include<map>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL long long
#define MP make_pair
using namespace std;
const LL mod=1e9+7;
LL base[4],pre[4][500010],inv[4];
struct node{LL a,b;}op[4][250010];
map<pair<pair<LL,LL>,pair<LL,LL> >,LL> mp;
LL pow(LL a,LL b)
{
LL ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;b>>=1;
}
return ans;
}
LL n,p=0,t[500010],c[4],a[4][250010],b[4][250010];
char s[250010];
void Pre()
{
for(int k=0;k<4;k++)
{
LL cnt=1;op[k][n+1].a=1;
for(LL i=n;i>=1;i--)
{
op[k][i]=op[k][i+1];
if(s[i]=='<') cnt=cnt*base[k]%mod,(op[k][i].a*=base[k])%=mod;
if(s[i]=='>') cnt=cnt*inv[k]%mod,(op[k][i].a*=inv[k])%=mod;
if(s[i]=='-') (op[k][i].b+=cnt*pre[k][n]%mod)%=mod;
if(s[i]=='+') op[k][i].b=((op[k][i].b-cnt*pre[k][n]%mod)%mod+mod)%mod;
}
}
}
void solve(LL *a,LL c,LL k) {for(LL i=1;i<=n;i++) a[i]=(c*op[k][i].a%mod+op[k][i].b)%mod;}
int main()
{
base[0]=2333;base[1]=10037;base[2]=19260817;base[3]