T1
题解
仔细分析了题目发现并不是后缀家族的(松口气
然后随便想了一个简单的思路,每次查询的时候遇到’)’就用链表遍历’(‘,然后遍历之间的’w’,至于’0’我们用一个树状数组查看w左边的‘0’个数和右边的‘0’个数乘积就是ans,然而这样的时间复杂度是很不稳妥的 O(n2logn) O ( n 2 l o g n ) ,60pts
然而这种区间修改单点修改我应该想到的———线段树
线段树维护区间内有多少(0w0)
区间内出现的答案分两种:
不跨越中线的:左右子区间答案相加
跨越中线的:分4种:
(0w0在左侧,)在右侧
(0w在左侧,0)在右侧
(0在左侧,w0)在右侧
(在左侧,0w0)在右侧
那么我们就需要维护每个区间内(,(0,(0w,(0w0,0w0),w0),0),)
那我们设f[i][j]表示颜文字i~j这一段在这个区间内出现的次数,那么
f[i][j]=fl[i][j]+fr[i][j]+∑j−1k=i(fl[i][k]+fr[k+1][j])
f
[
i
]
[
j
]
=
f
l
[
i
]
[
j
]
+
f
r
[
i
]
[
j
]
+
∑
k
=
i
j
−
1
(
f
l
[
i
]
[
k
]
+
f
r
[
k
+
1
]
[
j
]
)
那么时间复杂度为
O(nlogn)
O
(
n
l
o
g
n
)
,还有合并时候的常数,不是很大
代码
60pts
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
const LL mod=4294967296LL;
const int N=50005;
int n,num[N],m,nxtz[N],nxtw[N];char st[N];
void add(int loc,int vv){for (int i=loc;i<=n;i+=i&(-i)) num[i]+=vv;}
int qurry(int loc)
{
int ans=0;
for (int i=loc;i>=1;i-=i&(-i)) ans+=num[i];
return ans;
}
int main()
{
freopen("0w0.in","r",stdin);
freopen("0w0.out","w",stdout);
scanf("%d%d",&n,&m);
scanf("%s",st+1);
while (m--)
{
char w[5],c[5];int x,y;
scanf("%s",w);scanf("%d",&x);
if (w[0]=='B')
{
scanf("%d",&y);scanf("%s",c);
for (int i=x;i<=y;i++) st[i]=c[0];
}else if (w[0]=='A')
{
scanf("%s",c);
st[x]=c[0];
}else
{
scanf("%d",&y);LL ans=0;
for (int i=1;i<=n;i++) num[i]=0;
int pointz=0,pointw=0;
for (int i=x;i<=y;i++)
{
if (st[i]==')')
for (int j=pointz;j;j=nxtz[j])
for (int k=pointw;k;k=nxtw[k])
if (k<j) break;
else ans=(ans+(LL)(qurry(k)-qurry(j))*(LL)(qurry(i)-qurry(k))%mod)%mod;
if (st[i]=='(') nxtz[i]=pointz,pointz=i;
if (st[i]=='0') add(i,1);
if (st[i]=='w') nxtw[i]=pointw,pointw=i;
}
printf("%lld\n",ans);
}
}
}
100pts
这个模数直接用int自然溢出就行,最后%u
#include <cstdio>
#include <cstring>
#include <iostream>
#define LL long long
using namespace std;
const LL mod=4294967296LL;
const int N=50005;
int n,m,f[N*4][6][6],ans,tmpans;char st[N],delta[N*4];
//( 0 w 0 )
//1 2 3 4 5
int pd(char v)
{
if (v=='(') return 1;
if (v=='0') return 2;
if (v=='w') return 3;
if (v==')') return 5;
return 0;
}
void updata(int now,int l,int r)
{
for (int i=1;i<=5;i++)
for (int j=i;j<=5;j++)
{
f[now][i][j]=f[l][i][j]+f[r][i][j];
for (int k=i;k<j;k++) f[now][i][j]+=f[l][i][k]*f[r][k+1][j];
}
}
void pushdown(int now,int l,int r,int mid)
{
if (delta[now])
{
memset(f[now<<1],0,sizeof(f[now<<1]));
memset(f[now<<1|1],0,sizeof(f[now<<1|1]));
int sb=pd(delta[now]);
if (sb==2)
{
f[now<<1][2][2]=f[now<<1][4][4]=mid-l+1;
f[now<<1|1][2][2]=f[now<<1|1][4][4]=r-mid;
}else
{
f[now<<1][sb][sb]=mid-l+1;
f[now<<1|1][sb][sb]=r-mid;
}
delta[now<<1]=delta[now];
delta[now<<1|1]=delta[now];
delta[now]=0;
}
}
void build(int now,int l,int r)
{
if (l==r)
{
tmpans=max(now,tmpans);
if (st[l]=='(') f[now][1][1]=1;
else if (st[l]=='0') f[now][2][2]=f[now][4][4]=1;
else if (st[l]=='w') f[now][3][3]=1;
else if (st[l]==')') f[now][5][5]=1;
return;
}
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
updata(now,now<<1,now<<1|1);
}
void qurry(int now,int l,int r,int lrange,int rrange)
{
if (lrange<=l && rrange>=r)
{
updata(ans,tmpans,now);
memcpy(f[tmpans],f[ans],sizeof(f[tmpans]));
return;
}
int mid=(l+r)>>1;pushdown(now,l,r,mid);
if (lrange<=mid) qurry(now<<1,l,mid,lrange,rrange);
if (rrange>mid) qurry(now<<1|1,mid+1,r,lrange,rrange);
updata(now,now<<1,now<<1|1);
}
void change(int now,int l,int r,int lrange,int rrange,char v)
{
if (lrange<=l && rrange>=r)
{
delta[now]=v;
memset(f[now],0,sizeof(f[now]));
int sb=pd(v);
if (sb==2) f[now][2][2]=f[now][4][4]=r-l+1;
else f[now][sb][sb]=r-l+1;
return;
}
int mid=(l+r)>>1;pushdown(now,l,r,mid);
if (lrange<=mid) change(now<<1,l,mid,lrange,rrange,v);
if (rrange>mid) change(now<<1|1,mid+1,r,lrange,rrange,v);
updata(now,now<<1,now<<1|1);
}
int main()
{
freopen("0w0.in","r",stdin);
freopen("0w0.out","w",stdout);
scanf("%d%d",&n,&m);
scanf("%s",st+1);
build(1,1,n);
ans=0;tmpans++;
while (m--)
{
char w[5],c[5];int x,y;
scanf("%s",w);scanf("%d",&x);
if (w[0]=='B')
{
scanf("%d",&y);scanf("%s",c);
change(1,1,n,x,y,c[0]);
}else if (w[0]=='A') scanf("%s",c),change(1,1,n,x,x,c[0]);
else
{
scanf("%d",&y);
memset(f[ans],0,sizeof(f[ans]));
memset(f[tmpans],0,sizeof(f[tmpans]));
qurry(1,1,n,x,y);
printf("%u\n",f[ans][1][5]);
}
}
}
T2