6.13 NOI 模拟
\(T1\ first\)
\(bitset\)字符串匹配 \(yyds\)
\(O(\frac{n^2}{w})\)就是正解!
#include
#define MAXN 100005
using namespace std;
int q;
char s[MAXN],y[MAXN],in[MAXN];
bitsetSit[26],Ans;
int main()
{
scanf("%s",s+1);
for(int i=1;s[i];i++)
{
Sit[s[i]-'a'].set(i,1);
}
scanf("%d",&q);
for(int i=1,l,r,x,k,op;i<=q;i++)
{
scanf("%d",&op);
if(op==0)
{
char ch;
scanf("%d %c",&x,&ch);
Sit[s[x]-'a'].set(x,0);
s[x]=ch;
Sit[s[x]-'a'].set(x,1);
}
else
{
Ans.set();
int id=0;
scanf("%d",&k);
for(int j=1;j<=k;j++)
{
scanf("%s",in);
if(in[0]>='0'&&in[0]<='9')
{
int res=0;
for(int j=0;in[j];j++)
{
res=res*10+in[j]-'0';
}
for(int z=1;z<=res;z++) y[++id]='?';
}
else
{
for(int j=0;in[j];j++)
{
y[++id]=in[j];
}
}
}
int len=id;
scanf("%d%d",&l,&r);
for(int j=1;j<=id;j++)
{
if(y[j]=='?') continue;
Ans&=(Sit[y[j]-'a']>>(j-1));
}
printf("%d\n",max(0,(int)((Ans>>l).count()-(Ans>>(r-len+2)).count())));
}
}
}
\(T2\ second\)
最大流\(=\)最小割\(=\)平面图最短路
考虑维护矩阵
\(\begin{bmatrix} S_i & S_i+W_i\\ T_i+W_i & T_i\\ \end{bmatrix}\)
维护加法取\(\min\)矩阵就可以得到区间最大流了
本质上就是把有限的情况组合一下
矩阵乘法\(+\)循环展开食用更佳
#include
#define rs ((now<<1)|1)
#define int long long
#define ls (now<<1)
#define MAXN 500005
using namespace std;
char buf[1<<21],*p1,*p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
template
T Read()
{
T x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^'0');
ch=getchar();
}
return x*f;
}
int (*read)()=Read;
#define read Read
struct Mat
{
int jz[2][2];
void Init()
{
memset(jz,0x3f,sizeof(jz));
}
}zy[MAXN];
struct Seg
{
int l,r;
Mat Sum;
}tr[MAXN<<2];
int A[MAXN],B[MAXN],W[MAXN],n,q;
void build(int now,int l,int r)
{
tr[now].l=l;tr[now].r=r;
if(l==r) return ;
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
}
Mat mul(Mat a,Mat b)
{
Mat res;
res.Init();
res.jz[0][0]=min({a.jz[0][0]+b.jz[0][0],a.jz[0][1]+b.jz[1][0]});
res.jz[0][1]=min({a.jz[0][0]+b.jz[0][1],a.jz[0][1]+b.jz[1][1]});
res.jz[1][0]=min({a.jz[1][0]+b.jz[0][0],a.jz[1][1]+b.jz[1][0]});
res.jz[1][1]=min({a.jz[1][0]+b.jz[0][1],a.jz[1][1]+b.jz[1][1]});
return res;
}
void upd(int now)
{
tr[now].Sum=mul(tr[ls].Sum,tr[rs].Sum);
}
void change(int now,int poz)
{
if(tr[now].l==poz&&tr[now].r==poz)
{
tr[now].Sum=zy[poz];
return ;
}
int mid=(tr[now].l+tr[now].r)>>1;
if(poz<=mid) change(ls,poz);
else change(rs,poz);
upd(now);
}
Mat res;
Mat query(int now,int l,int r)
{
if(tr[now].l>=l&&tr[now].r<=r)
{
return tr[now].Sum;
}
int mid=(tr[now].l+tr[now].r)>>1;
if(l<=mid&&r>mid) return mul(query(ls,l,r),query(rs,l,r));
else if(l<=mid) return query(ls,l,r);
else if(r>mid) return query(rs,l,r);
}
void upd_poi(int x)
{
zy[x].jz[0][0]=A[x];
zy[x].jz[0][1]=A[x]+W[x];
zy[x].jz[1][0]=B[x]+W[x];
zy[x].jz[1][1]=B[x];
change(1,x);
}
signed main()
{
n=read(),q=read();
for(int i=1;i<=n;i++) A[i]=read();//scanf("%lld",&A[i]);
for(int i=1;i<=n;i++) B[i]=read();//scanf("%lld",&B[i]);
for(int i=1;i
\(T3\ third\)
\(DS\) 技不如人
#define Eternal_Battle ZXK
#include
using namespace std;
const int inf=1000000000;
struct edge{
int x,y;
};
struct node{
int l,r,fa,sz,s,v,la;
};
int n,m,k,colsum,x,y,ans,st[100011],tot,hd,idx[100011],edx[100011],edy[100011];
bool fl[100011];
vector vec[100011];
void getring(int a,int fa)
{
tot++;
st[tot]=a;
idx[a]=tot;
for(int i=0;i mp[100011];
void makenode(int a,int c)
{
p[a].sz=1;
p[a].v=c;
p[a].s=c;
}
void link(int a,int b)
{
cnt++;
t[cnt].x=b;
t[cnt].y=h[a];
h[a]=cnt;
}
void downtag(int a,int c)
{
if(!a)return;
p[a].v=p[a].v+c;
p[a].s=p[a].s+c;
p[a].la=p[a].la+c;
}
void down(int a)
{
p[a].fa=0;
downtag(p[a].l,p[a].la);
downtag(p[a].r,p[a].la);
p[a].la=0;
}
void up(int a){
int l=p[a].l,r=p[a].r;
p[l].fa=a;
p[r].fa=a;
p[a].s=min(p[a].v,min(p[l].s,p[r].s));
p[a].sz=p[l].sz+p[r].sz+1;
}
void split(int a,int c,int &l,int &r)
{
if(!a)
{
l=0;
r=0;
return;
}
down(a);
if(p[p[a].l].sz v;
for(int i=h[a];i;i=t[i].y)
{
if(t[i].x==father[a])continue;
father[t[i].x]=a;
int c=dfs(t[i].x);
if(col[a]!=col[t[i].x])downtag(c,1);
v[col[t[i].x]]=merge(v[col[t[i].x]],c);
ban=1;
}
if(ban)
{
for(auto i:v)
{
cnt++;
makenode(cnt,inf);
rt=merge(rt,cnt);
mp[a][i.first]=cnt;
rt=merge(rt,i.second);
cnt++;
makenode(cnt,inf);
rt=merge(rt,cnt);
}
}
else
{
if(!fl[a])
{
makenode(a,0);
rt=a;
}
else
{
rt=0;
}
}
cnt++;
makenode(cnt,inf);
rt=merge(cnt,rt);
f[a]=cnt;
cnt++;
makenode(cnt,inf);
rt=merge(rt,cnt);
return rt;
}
void build()
{
makenode(0,inf);
p[0].sz=0;
cnt=n;
root=dfs(1);
}
void update(int l,int r,int c)
{
int u,v,w;
split(root,r,u,w);
split(u,l-1,u,v);
downtag(v,c);
u=merge(u,v);
root=merge(u,w);
}
void turn(int a,int c)
{
if(mp[a][col[a]])update(getrank(mp[a][col[a]]),getrank(mp[a][col[a]]+1),1);
if(mp[a][c])update(getrank(mp[a][c]),getrank(mp[a][c]+1),-1);
if(a>1)
{
int fa=father[a],u,v,w,val1=getrank(f[a]),val2=getrank(f[a]+1);
split(root,val2,u,w);
split(u,val1-1,u,v);
if(col[father[a]]!=col[a])downtag(v,-1);
if(col[father[a]]!=c)downtag(v,1);
root=merge(u,w);
if(!mp[fa][c])
{
split(root,getrank(f[fa]),u,w);
cnt++;
makenode(cnt,inf);
u=merge(u,cnt);
mp[fa][c]=cnt;
cnt++;
makenode(cnt,inf);
u=merge(u,cnt);
root=merge(u,w);
}
split(root,getrank(mp[fa][c]),u,w);
u=merge(u,v);
root=merge(u,w);
}
col[a]=c;
}
}Ta,Tb;
int main(){
srand(19260817);
scanf("%d%d%d%d",&n,&m,&k,&colsum);
if(n==m)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&Ta.col[i]);
Tb.col[i]=Ta.col[i];
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
edx[i]=x;
edy[i]=y;
vec[x].push_back(y);
vec[y].push_back(x);
}
getring(1,0);
for(int i=1;i<=m;i++)
{
x=edx[i];
y=edy[i];
if(((x!=st[hd])||(y!=st[hd+1]))&&((x!=st[hd+1])||(y!=st[hd])))
{
Ta.link(x,y);
Ta.link(y,x);
}
if(((x!=st[hd])||(y!=st[tot]))&&((x!=st[tot])||(y!=st[hd])))
{
Tb.link(x,y);
Tb.link(y,x);
}
}
for(int i=hd;i<=tot;i++)fl[st[i]]=1;
Ta.build();
Tb.build();
ans=min(Ta.p[Ta.root].s,Tb.p[Tb.root].s);
printf("%d\n",ans);
for(int i=1;i<=k;i++)
{
scanf("%d%d",&x,&y);
Ta.turn(x,y);
Tb.turn(x,y);
ans=min(Ta.p[Ta.root].s,Tb.p[Tb.root].s);
printf("%d\n",ans);
}
}
else
{
for(int i=1;i<=n;i++)scanf("%d",&Ta.col[i]);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
Ta.link(x,y);
Ta.link(y,x);
}
Ta.build();
ans=Ta.p[Ta.root].s;
printf("%d\n",ans);
for(int i=1;i<=k;i++)
{
scanf("%d%d",&x,&y);
Ta.turn(x,y);
ans=Ta.p[Ta.root].s;
printf("%d\n",ans);
}
}
}