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普及组真题] 质因数分解 ...
随机推荐
- DEDECMS登录后台,无法连接数据库的原因
在CMS的网页模块中,当迁移网站出现后台无法登录的时候 最可能的情况有下列几种: 1. 数据库服务器宕机.如果是云上的数据库时,需要联系客服进行解决.是有自己的搭建的数据库,需要查看服务是否正常启动 ...
- 搭建NTP时间服务器~使用NTP同步时间~构建主机间时间自动同步关系
NTP是一个时间服务器,同时它也是一个时间客户端. 我们可以使用它构建主机与主机之间的时间自动同步环境,保证所有服务器时间一致性. 常用的公共NTP时间服务器有: cn.ntp.org.cn 中国 n ...
- 关于TornadoFx和Android的全局配置工具类封装实现及思路解析
原文地址: 关于TornadoFx和Android的全局配置工具类封装实现及思路解析 - Stars-One的杂货小窝 目前个人开发软件存在设置页面,可以让用户自定义些设置,但我发现,存储数据的代码逻 ...
- uniapp项目vue2升级vue3简单记录
看到好多开源项目都升级了vue3,看文章说vue3性能升级很多,而且组合式api很香,遂把最近开发的自助洗车app升级下,在此记录下出现的问题. uniapp升级vue3官方指南 我是先去vue官网看 ...
- 【物联网串口服务器通信经验教程】Modbus网关协议转换
在前面的文章中,我们已经详细地介绍了Modbus网关的几种主要类型,今天,就让我们来介绍一下其中简单协议转换的处理过程. 简单协议转换是最常规.最普遍的Modbus网关功能,也是数据处理效率最高Mod ...
- C# 将XML转为PDF
XML,即可扩展标记语言文,件是一种标准的文本文件,它使用特定的标记来描述文档的结构以及其他特性.通过将 XML 文档转换为 PDF格式,能够满足更多程序.设备对文件预览.读取或展示的需要,也更便于文 ...
- JS数组at函数(获取最后一个元素的方法)介绍
本文介绍js中数组的at函数,属于比较简单的知识普及性文章,难度不大. 0x00 首先,我们可以思考如下一个问题,如果要获取一个数组的最后一个元素(这是很常用的操作),我们应该怎么做? 相信大部分人能 ...
- python基础知识-day6(函数知识)
1.函数的特点 函数式的编程范式 面向对象的编程范式 所谓函数,就是把重复的代码单独的分离出来,放在一个公共的地方,以后可以一只调用,这样就可以解决多次重复来编写. 2.函数的定义 1 def fun ...
- Jenkins+Svn+Docker搭建持续集成环境 自动部署
一.准备工作: 两台服务器:192.168.206.212,192.168.206.213 自己新建一个maven项目 其中两台机子做下面的软件配置 212机子: 安装expect并配置: 安装jen ...
- 反向传播神经网络(BP)
实验部分: ①输入.输出矢量及问题的阐述 由题意输入变量取值范围为e={-2,-1,0,1,2}和ec={-2,-1,0,1,2},则输入矢量有25种情况,分别如下所示: 则由T=int((e+ec) ...