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普及组真题] 质因数分解 ...
随机推荐
- 75. Sort Colors - LeetCode
Question 75. Sort Colors Solution 题目大意: 给一个数组排序,这个数组只有0,1,2三个元素,要求只遍历一遍 思路: 记两个索引,lowIdx初始值为0,highId ...
- unity---UI管理模块
UI管理器 任务: 1.所有面板的父类,2.UIMgr 所有UI控件都继承UIBehaviour 面板基类 找到相应空间 简化后 也存在问题:一个物体可以同时挂载两个组件 导致键相同,而值不同, 将值 ...
- 135_Power Query M语言快捷输入之输入法设置自定义短语
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 因为工作原因,把电脑重装了下,当敲M的时候总感觉那里不对.原来是我的M自定义短语没有同步.由于我的自定义短语还是 ...
- 02-C高级编程
Day01 笔记 1 typedef使用 1.1 起别名 - 简化struct关键字 1.2 区分数据类型 1.3 提高代码移植性 2 void使用 2.1 不可以利用void创建变量 无法给无类型变 ...
- PyTorch DataLoader NumberWorkers Deep Learning Speed Limit Increase
这意味着训练过程将按顺序在主流程中工作. 即:run.num_workers. ,此外, ,因此,主进程不需要从磁盘读取数据:相反,这些数据已经在内存中准备好了. 这个例子中,我们看到了20%的加 ...
- C语言- 基础数据结构和算法 - 栈的顺序存储
听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...
- DS18B20数字温度计 (三) 1-WIRE总线 ROM搜索算法和实际测试
目录 DS18B20数字温度计 (一) 电气特性, 寄生供电模式和远距离接线 DS18B20数字温度计 (二) 测温, ROM和CRC算法 DS18B20数字温度计 (三) 1-WIRE总线 ROM搜 ...
- 开发工具-RSA加解密
更新日志 2022年6月10日 初始化链接. https://toolb.cn/rsa
- .NET中线程锁的使用
更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月1日. 一.说明 由于经常需要在多线程代码中使用Monitor进行同步,并且需要自己去手写try/finally块.因此C#提供了 ...
- 【Golang】程序如何优雅的退出?
1. 背景 项目开发过程中,随着需求的迭代,代码的发布会频繁进行,在发布过程中,如何让程序做到优雅的退出? 为什么需要优雅的退出? 你的 http 服务,监听端口没有关闭,客户的请求发过来了,但处理了 ...