这种使得整个串不包含子串’abc’的题目,发现可以用线段树维护
#include
using namespace std;
const int maxn=1e5+5;
#define lson now<<1
#define rson now<<1|1
struct seg
{
int a,b,c;
int ab,bc,abc;
}tr[maxn<<2];
int n,q;
char s[maxn];
void pushup(int now)
{
tr[now].a=tr[lson].a+tr[rson].a;
tr[now].b=tr[lson].b+tr[rson].b;
tr[now].c=tr[lson].c+tr[rson].c;
tr[now].ab=min(tr[lson].a+tr[rson].ab,tr[lson].ab+tr[rson].b);
tr[now].bc=min(tr[lson].b+tr[rson].bc,tr[lson].bc+tr[rson].c);
tr[now].abc=min(tr[lson].a+tr[rson].abc,min(tr[lson].ab+tr[rson].bc,tr[lson].abc+tr[rson].c));
}
void build(int now,int l,int r)
{
if(l==r)
{
if(s[l]=='a') tr[now].a=1;
if(s[l]=='b') tr[now].b=1;
if(s[l]=='c') tr[now].c=1;
return;
}
int mid=l+r>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
pushup(now);
}
void change(int now,int l,int r,int pos,char cc)
{
if(l==r)
{
tr[now].a=tr[now].b=tr[now].c=0;
if(cc=='a') tr[now].a=1;
if(cc=='b') tr[now].b=1;
if(cc=='c') tr[now].c=1;
return;
}
int mid=l+r>>1;
if(pos<=mid) change(lson,l,mid,pos,cc);
else change(rson,mid+1,r,pos,cc);
pushup(now);
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d%d",&n,&q);
scanf("%s",s+1);
build(1,1,n);
while(q--)
{
int x; char cc;
scanf("%d %c",&x,&cc);
change(1,1,n,x,cc);
printf("%d\n",tr[1].abc);
// change(1,1,n,x,s[x]);
}
return 0;
}
#include
using namespace std;
const int maxn=9e5+5;
typedef long long ll;
const ll mod=1e9+7;
int n,m,k;
ll pw[maxn],fac[maxn],inv[maxn],ifac[maxn];
ll C(ll x,ll y)
{
return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
pw[0]=1,fac[0]=inv[0]=ifac[0]=inv[1]=1;
for(int i=1;i<maxn;i++)
{
pw[i]=pw[i-1]*3%mod;
fac[i]=fac[i-1]*i%mod;
if(i>1) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
ifac[i]=ifac[i-1]*inv[i]%mod;
}
ll ans=0;
ll tmp;
// cerr<
for(int i=0;i<=k+m;i++)
{
ll res=C(n+i-1,i)*pw[m+k-i]%mod;
// cerr<
if(!i) tmp=1;
else
{
tmp=tmp*2%mod;
if(i>m) tmp=(tmp+mod-C(i-1,m))%mod;
if(i>k) tmp=(tmp+mod-C(i-1,i-k-1))%mod;
}
// cerr<
ans=(ans+res*tmp)%mod;
}
printf("%lld\n",ans);
return 0;
}
容易发现这种构造方式得到的串的0/1取决于二进制表示下1的个数的奇偶性,奇数个就是1,偶数个就是0
那么问题转换为从0开始和从n开始的m个数,有多少二进制下1的个数的奇偶性不同,然后就数位dp即可
注意使用1<#include