题解 [AGC020E] Encoding Subsets
Thaumaturge · · 个人记录
一开始的时候是毫无头绪的。
但是想一想,你可以发现
那怎么办呢?
我们现在有两种合并方法:第一种是取
他既然是要求所有子集,我们可以就让
我们大力猜测即使加上了并运算,
所以不能使用普通的区间
现在比较麻烦的是第二种情况,因为直接合并是会算重的。一开始是想记另外一个状态
另外这题可以锻炼你使用位运算的能力
/*************************************************************************
> File Name: AGC020E.cpp
> Author: The-Out-Land
> Mail: [email protected]
> Created Time: 2020年11月12日 星期四 11时28分34秒
************************************************************************/
#include <bits/stdc++.h>
#include <bits/extc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define re register
#define int long long
#define ll __int128
#define Vec vector<int>
#define N 210
#define Pii pair<ll,int>
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
using namespace std;
const int mod=998244353;
ll s,S;
char t[N];
map<Pii,pii> P;
int n,f[N][N],g[N];
Vec di[N];
inline int max(int x,int y){return (x>y?x:y);}
inline int min(int x,int y){return (x<y?x:y);}
inline ll read(){
ll x=0;char c=getchar();bool y=1;
for(;c<'0' || c>'9';c=getchar()) if(c=='-') y=0;
for(;c>='0' && c<='9';c=getchar()) x=(x<<1)+(x<<3)+c-48;
if(y) return x;
return -x;
}
int st[100],top;
inline void write(ll x,char c){
if(x<0) putchar('-');
while(x) st[++top]=x%10,x/=10;
if(!top) putchar('0');
while(top) putchar(st[top--]+'0');
putchar(c);
return;
}
inline int add(int x){
if(x<0) return x+mod;
return (x>=mod?x-mod:x);
}
inline void merge(ll x,int w){
if(P.find(mp(x,w))!=P.end()) return;
if(w==1) return P[mp(x,w)]=mp((int)x+1,x+1),void();
int sz=di[w].size(),d,ans=0,ans2=0,tot=1;
ll now,U;
for(re int i=0;i<sz;++i){
d=w/di[w][i];
now=U=(1ll<<d)-1;
for(re int j=0;j<w;j+=d){
now&=(x>>j&U);
}
merge(now,d);
ans=add(ans+P[mp(now,d)].fi);
}
for(re int i=1;i<w;++i){
merge(x>>i,w-i);
merge(x^(x>>i<<i),i);
ans2=(ans2+P[mp(x^(x>>i<<i),i)].fi*P[mp(x>>i,w-i)].se)%mod;
}
return P[mp(x,w)]=mp(add(ans+ans2),ans),void();
}
inline void Input(){
scanf("%s",t+1);
n=strlen(t+1);
for(re int i=n;i;--i)
S=(S<<1)+(t[i]^'0');
for(re int i=2;i<=n;++i){
for(re int j=i;j<=n;j+=i)
di[j].push_back(i);
}
return;
}
inline void solve(){
merge(S,n);
printf("%lld\n",P[mp(S,n)].fi);
return;
}
signed main(){
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
Input();
solve();
return 0;
}
真不错啊。。