6.13 NOI 模拟
\(T1\ first\)
\(bitset\)字符串匹配 \(yyds\)
\(O(\frac{n^2}{w})\)就是正解!
#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
int q;
char s[MAXN],y[MAXN],in[MAXN];
bitset<MAXN>Sit[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<bits/stdc++.h>
#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<class T>
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<int>;
#define read Read<int>
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<n;i++) W[i]=read();//scanf("%lld",&W[i]);
build(1,1,n);
for(int i=1;i<=n;i++) upd_poi(i);
for(int i=1,l,r,x,v,op;i<=q;i++)
{
op=read();
if(op==1)
{
x=read(); v=read();
A[x]=v;
upd_poi(x);
}
else if(op==2)
{
x=read(); v=read();
B[x]=v;
upd_poi(x);
}
else if(op==3)
{
x=read(); v=read();
W[x]=v;
upd_poi(x);
}
else
{
l=read(); r=read();
Mat res=query(1,l,r);
printf("%lld\n",min({res.jz[0][0],res.jz[0][1],res.jz[1][0],res.jz[1][1]}));
}
}
}
\(T3\ third\)
\(DS\) 技不如人
#define Eternal_Battle ZXK
#include<bits/stdc++.h>
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<int> vec[100011];
void getring(int a,int fa)
{
tot++;
st[tot]=a;
idx[a]=tot;
for(int i=0;i<vec[a].size();i++)
{
if(vec[a][i]==fa)continue;
if(idx[vec[a][i]]){
hd=idx[vec[a][i]];
return;
}
getring(vec[a][i],a);
if(hd)return;
}
tot--;
}
struct fhqtree
{
int root,cnt,h[100011],col[100011],f[100011],father[100011];
edge t[200011];
node p[1000011];
map<int,int> 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<c)
{
l=a;
split(p[a].r,c-p[p[a].l].sz-1,p[a].r,r);
}
else
{
r=a;
split(p[a].l,c,l,p[a].l);
}
up(a);
}
int merge(int a,int b)
{
if(a==0||b==0)return a+b;
if(rand()%(p[a].sz+p[b].sz)<p[a].sz)
{
down(a);
p[a].r=merge(p[a].r,b);
up(a);
return a;
}
down(b);
p[b].l=merge(a,p[b].l);
up(b);
return b;
}
int getrank(int a)
{
int s=p[p[a].l].sz+1,fa=p[a].fa;
while(fa)
{
if(p[fa].r==a)s=s+p[p[fa].l].sz+1;
a=fa;
fa=p[a].fa;
}
return s;
}
int dfs(int a)
{
int rt=0,ban=0;
map<int,int> 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);
}
}
}
6.13 NOI 模拟的更多相关文章
- 5.30 NOI 模拟
$5.30\ NOI $模拟 高三大哥最后一次模拟考了,祝他们好运 \(T1\)装箱游戏 显然可以将四种字母之间的空缺当做状态枚举 那么这道题就很显然了 #include<bits/stdc++ ...
- 5.23 NOI 模拟
$5.23\ NOI $模拟 \(T1\)简单的计算几何题 \(zjr:\)我当时没改,那么自己看题解吧 倒是有个简单的随机化方法(能获得\(72pts,\)正确性未知)\(:\) 随机两条切椭圆的平 ...
- 5.6 NOI模拟
\(5.6\ NOI\)模拟 明天就母亲节了,给家里打了个电话(\(lj\ hsez\)断我电话的电,在宿舍打不了,只能用教练手机打了) 其实我不是很能看到自己的\(future,\)甚至看不到高三的 ...
- 5.4 NOI模拟
\(5.4\ NOI\)模拟 \(T1\) 想到分讨,但是暴力输出一下方案之后有很多特别的情况要讨论,就弃了... 假设\(a\)是原序列,\(b\)是我们得到的序列 设\(i\)是最长公共前缀,\( ...
- 2018/3/13 noiρ[rəʊ]模拟赛 125分
T1 60分暴力,水分也不会水,打表也不会打,正解是不可能写正解的,这辈子都写不出来正解的,虽然是zz题但是也拿不到分这样子. 正解:(啥?正解是sb组合数?这都他娘的想不到,真鸡儿丢人我自杀吧.) ...
- NOI模拟赛(3.13)Hike (远行)
Description Mirada生活的城市中有N个小镇,一开始小镇之间没有任何道路连接.随着经济发展,小镇之间陆续建起了一些双向的道路,但是由于经济不太发达,在建设过程中,会保证对于任意两个小镇, ...
- 13.6 模拟事件【JavaScript高级程序设计第三版】
事件,就是网页中某个特别值得关注的瞬间.事件经常由用户操作或通过其他浏览器功能来触发. 但很少有人知道,也可以使用JavaScript 在任意时刻来触发特定的事件,而此时的事件就如同浏览器创建的事件一 ...
- NOI模拟赛 Day1
[考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...
- NOIP2012 普及组真题 4.13校模拟
考试状态: 我今天抽签看了洛谷的… 这我能怂???凶中带吉,我怕考试??我!不!怕! 看着整个机房的男同学们,我明白我是不会触发我的忌了.很好,开刷. A. [NOIP2012普及组真题] 质因数分解 ...
随机推荐
- 基于 BaGet 搭建 Nuget 服务器
1 前言 1.1 BaGet 介绍 BaGet 是一个轻量级的,开源的,跨平台的 Nuget 和 symbol 服务器. 1.2 环境介绍 操作系统:CentOS 7 使用 Docker 安装 2 安 ...
- uniapp项目vue2升级vue3简单记录
看到好多开源项目都升级了vue3,看文章说vue3性能升级很多,而且组合式api很香,遂把最近开发的自助洗车app升级下,在此记录下出现的问题. uniapp升级vue3官方指南 我是先去vue官网看 ...
- SpringCloud 客户端负载均衡:Ribbon
目录 Ribbon 介绍 开启客户端负载均衡,简化 RestTemplate 调用 负载均衡策略 Ribbon 介绍 Ribbon 是 Netflix 提供的一个基于 Http 和 TCP 的客户端负 ...
- SQL Server各版本序列号/激活码/License/秘钥
SQL Server 2019 Enterprise:HMWJ3-KY3J2-NMVD7-KG4JR-X2G8G Enterprise Core:2C9JR-K3RNG-QD4M4-JQ2HR-846 ...
- Chrome自带功能实现网页截图
更新记录 本文迁移自Panda666原博客,原发布时间:2021年6月28日. 很简单,按下Ctrl+Shift+P,打开命令行窗口,如下图所示. 输入命令. Capture full size sc ...
- 微信access_token缓存与更新
由于Access Token有效期只有7200秒,而每天调用获取的次数只有2000次,所以需要将Access Token进行缓存来保证不触发超过最大调用次数.另外在微信公众平台中,绝大多数高级接口都需 ...
- 解开XAML的邪恶面纱
什么是XAML,首先我们看下它的外观 <Window x:Class="Blend_WPF.WindowStyle" xmlns="http://sc ...
- Java 将HTML转为Word
本文以Java代码为例介绍如何实现将HTML文件转为Word文档(.docx..doc).在实际开发场景中可参考此方法来转换.下面详细方法及步骤. 在编辑代码前,请先在程序中导入Spire.Doc.j ...
- 『现学现忘』Docker基础 — 41、将本地镜像推送到阿里云
目录 1.准备工作 2.阿里云容器镜像仓库的使用 (1)创建命名空间 (2)创建容器镜像 (3)查看阿里云镜像仓库的信息 3.将本地Docker镜像推送到阿里云 (1)登陆阿里云 (2)给镜像生成版本 ...
- gitlab和jenkins做持续集成构建教程
背景介绍 上一个轮回,我花了三篇文章的时间着重向大家介绍了在条件有限的情况下,如果优雅地进行前端发版和迭代.庆七一,热烈庆祝香港回归,人民生活水平越来越好,昨天上午我自掏腰包买了台服务器,决定由冷兵器 ...