专题突破三之并查集Ⅰ——Portal,parity,食物链,程序自动分析,Almost Union-Find,洞穴勘测

文章目录

  • Portal
  • parity
  • [NOI2001] 食物链
  • 程序自动分析
  • UVA11987 Almost Union-Find
  • [SDOI2008] 洞穴勘测

Portal

source

百度翻译简直就是个鬼…(((m -__-)m

离线

将边和询问按权值排序,指针,将所有权值不超过当前询问iii的边全加进去

答案路径自然是不连通的两点sizsizsiz之积

原本就联通的,新加边不产生贡献

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 10005
#define maxm 50005
#define int long long
struct node {int u, v, w;
}edge[maxm];
pair < int, int > query[maxn];
int n, m, Q, cnt;
int f[maxn], siz[maxn], ans[maxn];void makeset() {for( int i = 1;i <= n;i ++ ) f[i] = i, siz[i] = 1;
}int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}void merge( int u, int v ) {u = find( u ), v = find( v );if( u == v ) return;else {f[v] = u;cnt += siz[u] * siz[v];siz[u] += siz[v];}
}signed main() {while( ~ scanf( "%lld %lld %lld", &n, &m, &Q ) ) {cnt = 0;for( int i = 1;i <= m;i ++ )scanf( "%lld %lld %lld", &edge[i].u, &edge[i].v, &edge[i].w );sort( edge + 1, edge + m + 1, []( node x, node y ) { return x.w < y.w; } );for( int i = 1;i <= Q;i ++ ) {scanf( "%lld", &query[i].first );query[i].second = i;}sort( query + 1, query + Q + 1 );makeset();int j = 1;for( int i = 1;i <= Q;i ++ ) {while( j <= m && edge[j].w <= query[i].first ) merge( edge[j].u, edge[j].v ), j ++;ans[query[i].second] = cnt;}for( int i = 1;i <= Q;i ++ )printf( "%lld\n", ans[i] );}return 0;
}

parity

source

一般判断是否矛盾的并查集肯定是带权并查集

将区间[l,r][l,r][l,r]的奇偶当作r→l−1r\rightarrow l-1rl1的权值

判断矛盾,首先l−1,rl-1,rl1,r要在同一个并查集,然后看之间的权值是否与当前条件的奇偶矛盾

#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 10005
struct node {int l, r;char opt[10];
}query[maxn];
int n, m;
int x[maxn], f[maxn], sum[maxn];void makeset() {for( int i = 0;i <= n;i ++ )f[i] = i, sum[i] = 0;
}int find( int x ) {if( x == f[x] ) return x;else {int fa = find( f[x] );sum[x] = ( sum[x] + sum[f[x]] ) % 2;return f[x] = fa;}
}int main() {next :while( scanf( "%d", &n ) && ~ n ) {scanf( "%d", &m );n = 0;for( int i = 1;i <= m;i ++ ) {scanf( "%d %d %s", &query[i].l, &query[i].r, query[i].opt );x[++ n] = query[i].l;x[++ n] = query[i].r;}sort( x + 1, x + n + 1 );n = unique( x + 1, x + n + 1 ) - x - 1;makeset();for( int i = 1;i <= m;i ++ ) {int l = lower_bound( x + 1, x + n + 1, query[i].l ) - x;int r = lower_bound( x + 1, x + n + 1, query[i].r ) - x;int t = query[i].opt[0] == 'o';if( l > r ) swap( l, r );l --;int u = find( l ), v = find( r );if( u ^ v ) {f[v] = u;sum[v] = ( -sum[r] + sum[l] + t + 2 ) % 2;}elseif( t )if( sum[l] == sum[r] ) {printf( "%d\n", i - 1 );goto next;} else;elseif( sum[l] != sum[r] ) {printf( "%d\n", i - 1 );goto next;} else;}printf( "%d\n", m );}return 0;
}

[NOI2001] 食物链

source

法一:建虚点

因为题目的食物链是个三元环,天然有我是 我的天敌的天敌 的天敌

i+ni+ni+n集合表示iii能吃的,i+2ni+2ni+2n表示iii能被吃的

大力情况枚举讨论

#include <cstdio>
#define maxn 150005
int f[maxn];
int n, m, ans;void makeset() {for( int i = 1;i <= n * 3;i ++ )f[i] = i;
}int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}void merge( int u, int v ) {u = find( u ), v = find( v );f[v] = u;
}
/*
i: itself
i+n:i can eat them
i+2*n:they can eat i
*/
int main() {scanf( "%d %d", &n, &m );makeset();for( int i = 1, d, x, y;i <= m;i ++ ) {scanf( "%d %d %d", &d, &x, &y );if( x > n || y > n ) ans ++;elseif( d & 1 ) {if( find( x ) == find( y + n ) or find( x + n ) == find( y ) or find( x ) == find( y + n * 2 ) or find( x + n * 2 ) == find( y ) ) ans ++;else merge( x, y ), merge( x + n, y + n ), merge( x + n * 2, y + n * 2 );}else {if( x == y ) ans ++;else if( find( x ) == find( y ) or find( x ) == find( y + n ) or find( x + n * 2 ) == find( y ) )ans ++;elsemerge( x, y + n * 2 ), merge( x + n, y ), merge( x + n * 2, y + n );}}printf( "%d\n", ans );return 0;
}

法二:带权并查集

在这里插入图片描述

不在同一个并查集的u,vu,vu,v两点,连向自己祖先的权值为sumu,sumvsum_u,sum_vsumu,sumv

如果现在将u,vu,vu,v合并,并且是vvv合并到uuu,那么就是fv→fuf_v\rightarrow f_ufvfu

权值显然为valfv=−sumv+sumu+wval_{f_v}=-sum_v+sum_u+wvalfv=sumv+sumu+w

在这里插入图片描述
路径压缩的时候,权值更新需要以前的直系父亲权值即可

回归本题,将同类看作边权为000,吃关系看成边权为111,在(mod3)\pmod 3(mod3)意义下做

#include <cstdio>
#define maxn 50005
int n, k, ans;
int f[maxn], sum[maxn];void makeset() {for( int i = 1;i <= n;i ++ ) f[i] = i;
}int find( int x ) {if( x == f[x] ) return x;else {int fa = f[x];f[x] = find( f[x] );sum[x] = ( sum[x] + sum[fa] ) % 3;return f[x];}
}int main() {scanf( "%d %d", &n, &k );makeset();for( int i = 1, d, x, y;i <= k;i ++ ) {scanf( "%d %d %d", &d, &x, &y );if( x > n || y > n ) ans ++;else {int fx = find( x ), fy = find( y );if( d & 1 )if( fx == fy && sum[x] != sum[y] ) ans ++;else if( fx ^ fy ) f[fx] = fy, sum[fx] = ( -sum[x] + sum[y] + 3 ) % 3;else;else {if( x == y ) ans ++;else if( fx == fy )if( ( sum[x] - sum[y] + 3 ) % 3 != 1 ) ans ++;else;else f[fx] = fy, sum[fx] = ( -sum[x] + sum[y] + 4 ) % 3;}}}printf( "%d\n", ans );return 0;
}

程序自动分析

source

离散,先一股脑把所有相等的并查集到一起,最后判断不等的两个数是否在同一个集合即可

luogu上面好几篇都是错的,对拍直接挂掉,这用脚造的数据诶

#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 4000005
struct node {int u, v, e;
}lim[maxn];
int T, n;
int f[maxn], x[maxn];void makeset() {for( int i = 1;i <= ( n << 2 );i ++ ) f[i] = i;
}int find( int x ) {return f[x] == x ? x : f[x] = find( f[x] );
}void merge( int u, int v ) {u = find( u ), v = find( v );f[v] = u;
}int main() {scanf( "%d", &T );next :while( T -- ) {scanf( "%d", &n );makeset();int cnt = 0;for( int i = 1;i <= n;i ++ ) {scanf( "%d %d %d", &lim[i].u, &lim[i].v, &lim[i].e );x[++ cnt] = lim[i].u, x[++ cnt] = lim[i].v;}sort( x + 1, x + cnt + 1 );cnt = unique( x + 1, x + cnt + 1 ) - x - 1;for( int i = 1;i <= n;i ++ ) {int u = lim[i].u, v = lim[i].v, e = lim[i].e;u = lower_bound( x + 1, x + cnt + 1, u ) - x;v = lower_bound( x + 1, x + cnt + 1, v ) - x;if( e ) merge( u, v );}for( int i = 1;i <= n;i ++ ) {int u = lim[i].u, v = lim[i].v, e = lim[i].e;u = lower_bound( x + 1, x + cnt + 1, u ) - x;v = lower_bound( x + 1, x + cnt + 1, v ) - x;if( ! e && find( u ) == find( v ) ) {printf( "NO\n" );goto next;}}printf( "YES\n" );}return 0;
}

UVA11987 Almost Union-Find

source

可删除并查集

建虚点

相当于套个盒子,然后父子关系就是盒子上面的互相指代,但是数就可以不存在(盒子存在)

在这里插入图片描述

#include <cstdio>
#define maxn 200005
int n, m;
int f[maxn], sum[maxn], siz[maxn];void makeset() {for( int i = n + 1;i <= ( n << 1 );i ++ ) f[i] = i, sum[i] = i - n, siz[i] = 1;for( int i = 1;i <= n;i ++ ) f[i] = i + n;
}int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}int main() {while( ~ scanf( "%d %d", &n, &m ) ) {makeset();for( int i = 1, opt, p, q, u, v;i <= m;i ++ ) {scanf( "%d %d", &opt, &p );switch ( opt ) {case 1 : {scanf( "%d", &q );u = find( p ), v = find( q );if( u == v ) continue; else;f[v] = u, siz[u] += siz[v], sum[u] += sum[v];siz[v] = sum[v] = 0;break;}case 2 : {scanf( "%d", &q );u = find( p ), v = find( q );if( u == v ) continue; else;f[p] = v;sum[v] += p, sum[u] -= p;siz[u] --, siz[v] ++;break;}case 3 : {u = find( p );printf( "%d %d\n", siz[u], sum[u] );break;}}}}return 0;
}

[SDOI2008] 洞穴勘测

source

线段树+可撤销并查集

每条边存在的时间是一个区间,丢在线段树上,最多log⁡n\log nlogn个标记

然后dfs遍历到每个叶子节点,判断这个iii是否有询问挂在上面,再判断此刻已有边中两点是否联通

第一次经过点num\rm numnum,就把挂在上面的边操作加入并查集,先后顺序记录操作的边

dfs回溯再次经过该点的时候,就倒着把这些边的操作反着做,从而起到抵消边的效果

#include <map>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define maxn 200005
#define Pair pair < int, int >
struct node {int u, v, w;node(){}node( int U, int V, int W ) {u = U, v = V, w = W;}
}query[maxn];
vector < Pair > E[maxn << 2];
map < Pair, int > mp;
int n, m, top;
int f[maxn], siz[maxn], ans[maxn];
Pair sta[maxn];void makeset() {for( int i = 1;i <= n;i ++ ) f[i] = i, siz[i] = 1;
}int find( int x ) {return x == f[x] ? x : find( f[x] );
}void insert( int num, int l, int r, int L, int R, Pair t ) {if( r < L or R < l ) return;if( L <= l and r <= R ) {E[num].push_back( t );return;}int mid = ( l + r ) >> 1;insert( num << 1, l, mid, L, R, t );insert( num << 1 | 1, mid + 1, r, L, R, t );
}void merge( int u, int v ) {u = find( u ), v = find( v );if( u ^ v ) {if( siz[u] < siz[v] ) swap( u, v );sta[++ top] = make_pair( u, v );siz[u] += siz[v], siz[v] ++;f[v] = u;}
}void Delete( int last ) {while( top > last ) {Pair t = sta[top --];siz[t.second] --;siz[t.first] -= siz[t.second];f[t.second] = t.second;}
}void dfs( int num, int l, int r ) {int now = top;for( auto edge : E[num] )merge( edge.first, edge.second );if( l == r ) {if( query[l].w ) {if( find( query[l].u ) == find( query[l].v ) ) ans[l] = 1;elseans[l] = -1;}}else {int mid = ( l + r ) >> 1;dfs( num << 1, l, mid );dfs( num << 1 | 1, mid + 1, r );}Delete( now );
}int main() {scanf( "%d %d", &n, &m );makeset();char opt[10]; int u, v;for( int i = 1;i <= m;i ++ ) {scanf( "%s %d %d", opt, &u, &v );if( u > v ) swap( u, v );Pair t = make_pair( u, v );switch ( opt[0] ) {case 'C' : {mp[t] = i;break;}case 'D' : {insert( 1, 1, m, mp[t], i, t );mp.erase( t );break;}case 'Q' : {query[i] = node( u, v, 1 );break;}}}for( map < Pair, int > :: iterator it = mp.begin();it != mp.end();it ++ )insert( 1, 1, m, it -> second, m, it -> first );dfs( 1, 1, m );for( int i = 1;i <= m;i ++ )if( ! ans[i] ) continue;else puts( ans[i] > 0 ? "Yes" : "No" );return 0;
}
#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 300005
#define LL long long
struct node {int f, flag, son[2], sum, val;
}tree[maxn];
int n, m;
int st[maxn];void reverse ( int x ) {swap ( tree[x].son[0], tree[x].son[1] );tree[x].flag ^= 1;
}void update ( int x ) {tree[x].sum = tree[tree[x].son[0]].sum + tree[tree[x].son[1]].sum + tree[x].val;
}void pushdown ( int x ) {if ( tree[x].flag ) {if ( tree[x].son[0] )reverse ( tree[x].son[0] );if ( tree[x].son[1] )reverse ( tree[x].son[1] );tree[x].flag = 0;}
}bool isroot ( int x ) {return tree[tree[x].f].son[0] == x || tree[tree[x].f].son[1] == x;
}void rotate ( int x ) { int fa = tree[x].f; int Gfa = tree[fa].f;int k = ( tree[fa].son[1] == x );if ( isroot ( fa ) )tree[Gfa].son[tree[Gfa].son[1] == fa] = x;tree[x].f = Gfa; tree[fa].son[k] = tree[x].son[k ^ 1];if ( tree[x].son[k ^ 1] )tree[tree[x].son[k ^ 1]].f = fa;tree[x].son[k ^ 1] = fa;tree[fa].f = x;update ( fa );update ( x );
}void splay ( int x ) {int Top = 0, y = x;st[++ Top] = y;while ( isroot ( y ) )st[++ Top] = y = tree[y].f;while ( Top )pushdown ( st[Top -- ] );while ( isroot ( x ) ) {int fa = tree[x].f, Gfa = tree[fa].f;if ( isroot ( fa ) )( ( tree[Gfa].son[0] == fa ) ^ ( tree[fa].son[0] == x ) ) ? rotate ( x ) : rotate ( fa );rotate ( x );}
}void access ( int x ) {for ( int son = 0;x;son = x, x = tree[x].f ) {splay ( x );tree[x].son[1] = son;update ( x );}
}void MakeRoot ( int x ) {access ( x );splay ( x );reverse ( x );
}int FindRoot ( int x ) {access ( x );splay ( x );while ( tree[x].son[0] ) {pushdown ( x );x = tree[x].son[0];}splay ( x );return x;
}void split ( int x, int y ) { MakeRoot ( x );access ( y );splay ( y );
}bool link ( int x, int y ) {MakeRoot ( x );if ( FindRoot ( y ) == x )return 0;tree[x].f = y;return 1;
}void cut ( int x, int y ) { MakeRoot ( x );if ( FindRoot ( y ) != x || tree[y].f != x || tree[y].son[0] )return;tree[y].f = tree[x].son[1] = 0;update ( x );
}int main() {scanf ( "%d %d", &n, &m );int x, y;char opt[15];for ( int i = 1;i <= m;i ++ ) {scanf ( "%s %d %d", &opt, &x, &y );switch ( opt[0] ) {case 'Q' : {MakeRoot ( x );if ( FindRoot ( y ) == x )printf ( "Yes\n" );elseprintf ( "No\n" );break;}case 'C' : link ( x, y ); break;case 'D' : cut ( x, y ); break;}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 未来新特性:静态委托和函数指针

C# 每发布一次新版本&#xff0c;都会增加一些底层相关的新特性&#xff0c; 这些特性对大多数商业程序来说并没什么实际用处&#xff0c;主要用于那些对性能有很高要求的代码&#xff0c;如图形处理、机器学习以及数学工具包&#xff0c;等等。接下来的两个提案&#xff0c;主…

CF700E Cool Slogans(SAM,dp)

解析 好题。 首先&#xff0c;我们每次都令 sis_isi​ 是 si1s_{i1}si1​ 的后缀&#xff0c;肯定是不劣的 问题就可以转化到 fail 树上了 首先肯定要线段树合并处理出endpos集合 朴素想法&#xff1a;设父亲 fafafa 的结束位置为 posfapos_{fa}posfa​&#xff0c;若 [posfa−…

pjudge#21651-[PR #4]猜猜看【交互】

正题 题目链接:http://pjudge.ac/problem/21651 题目大意 有一个1∼n1\sim n1∼n的排列&#xff0c;每次你可以询问 iii和jjj的大小关系i,j,ki,j,ki,j,k的中位数 现在要求在222次111操作和2n2n2n次222操作内得到这个排列。 50≤n≤510550\leq n\leq 5\times 10^550≤n≤5105…

JavaWeb --第一章Web基本概念

JavaWeb --第一章Web基本概念 文章目录基本概念前言web开发&#xff1a;web应用程序静态web动态webweb服务器技术讲解web服务器基本概念 前言 web开发&#xff1a; web&#xff0c;网页的意思静态web a. html&#xff0c;css b. 提供给所有人看的数据始终不会发生改变动态we…

DotNetty 实现 Modbus TCP 系列 (二) ModbusFunction 类图及继承举例

DotNetty 实现 Modbus TCP 系列 (一) 报文类ModbusFunction 类图如下&#xff1a;如前文所述&#xff0c;所有请求/相应的 PDU 均继承自 ModbusFunction&#xff0c;其子类传入对应的 Function Code 并实现三个方法&#xff1a;CalculateLength&#xff1a;Data 部分的长度(该方…

AT2366-[AGC012F]Prefix Median【dp】

正题 题目链接:https://www.luogu.com.cn/problem/AT2366 题目大意 有一个长度为2n−12n-12n−1的序列aaa&#xff0c;你可以将其重新排列&#xff0c;定义bib_ibi​为a1∼2i−1a_{1\sim 2i-1}a1∼2i−1​的中位数。 询问有多少种不同的可能的bbb序列。 1≤n≤501\leq n\leq…

专题突破三之并查集Ⅱ——星球大战,In Touch,方格染色,Junk-Mail Filter,关押罪犯,Silver Woods,Must Be Rectangular!

文章目录[JSOI2008]星球大战In Touch方格染色Junk-Mail Filter[NOIP2010 提高组] 关押罪犯Silver WoodsMust Be Rectangular![JSOI2008]星球大战 source 非常套路的&#xff0c;正着打击星球&#xff0c;逆着就是添加星球以及关系&#xff0c;并查集维护此时连通块个数 就是…

模板:整体二分

所谓整体二分&#xff0c;就是对整体进行二分 &#xff08;逃&#xff09; 前言 又是一个狂艹树套树的小清新分治算法 但是树套树不需要动脑啊 整体二分有一些比较重要的条件&#xff1a; 修改对判定答案的贡献互相独立&#xff0c;修改之间互不影响效果修改如果对判定答案有…

JavaWeb --第二章 Tomact详情

JavaWeb --第二章 Tomact详情 文章目录Tomcat安装TomcatTomcat启动和配置配置发布一个web网站Tomcat 安装Tomcat 去官方下载 https://tomcat.apache.org Tomcat启动和配置 文件夹作用&#xff1a; 启动/关闭 Tomcat&#xff1a; 文件夹bin/startup.bat 开启 网址&#x…

P8352-[SDOI/SXOI2022]小N的独立集【dp套dp】

正题 题目链接:https://www.luogu.com.cn/problem/P8352 题目大意 给出一棵树&#xff0c;每个点的权值是[1,k][1,k][1,k]之间的一个数&#xff0c;对于i∈[1,nk]i\in[1,nk]i∈[1,nk]求令这棵树的最大独立集权值为iii的方案数。 1≤n≤1000,1≤k≤51\leq n\leq 1000,1\leq k\…

开源的类似于Apache ab的压力测试命令行工具SuperBenchmarker

SuperBenchmarker 是ㄧ个开源的类似于Apache ab的压力测试命令行工具。可以在 .NET 4.52 或者 .NET Core 2.0 平台上运行。可支持Get、Post、Put、Delete这些调用方式&#xff0c;调用时能指定Concurrent user、Request数、Header template…等。可以从Github、Chocolatey这两种…

CodeForces:643(VK cup)

文章目录前言CF643A Bear and ColorsDescription\text{Description}DescriptionSolution\text{Solution}SolutionDescription\text{Description}DescriptionCF643B Bear and Two PathsDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}…

一二三系列之优先队列、st表——Battle,Heapsort,A Magic Lamp

文章目录BattleHeapsortA Magic LampBattle source 如果怪兽先死&#xff0c;那么英雄血量不足也没关系 反悔贪心 每次都先杀怪兽再说&#xff0c;如果血量不够了&#xff0c;就倒回去从怪兽打出伤害由高到低反悔&#xff0c;选择抵御或者加血&#xff0c;肯定哪个加的更多…

JavaWeb --第三章 HTTP协议详解

JavaWeb --第三章 HTTP协议详解 Http 什么是HTTP HTTP&#xff1a; 超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff0c;HTTP&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。 文本&#xff1a;html&#xff0c;字符串&#xff0c…

AT2382-[AGC015D]A or...or B Problem

正题 题目链接:https://www.luogu.com.cn/problem/AT2382 题目大意 询问在[L,R][L,R][L,R]中选取一个或多个数&#xff0c;将它们按位或后能得到多少种不同的结果。 1≤L≤R<2601\leq L\leq R<2^{60}1≤L≤R<260 解题思路 我们先把高位的LLL和RRR都有的111都删除&a…

数据结构一【树状数组】普通、二维、离线树状数组的(单点修改,单点查询,区间修改,区间查询)模板及应用例题总结

文章目录树状数组lowbit线段树与树状数组单点修改区间查询区间修改区间求和二维树状数组离线树状数组例题POJ&#xff1a;starsMooFest[SDOI2009]HH的项链Turing TreeCounting SequencesZip-line树状数组 用于快速高效的计算与前缀和相关的信息 lowbit int lowbit( int i ) …

如何优雅的利用Windows服务来部署ASP.NET Core程序

上一篇文章中我给大家讲述了五种部署ASP.NET Core网站的方法&#xff0c;其中有一种方式是通过Windows服务来进行部署&#xff0c;这样既可以做到开启自启动&#xff0c;又不会因为iis的反向代理而损失部分性能。但是美中不足的是需要借助第三方软件nssm来进行&#xff0c;那么…

JavaWeb --第四章Maven详解

JavaWeb --第四章Maven详解 文章目录MavenMaven架构管理工具下载安装Maven配置环境变量阿里云镜像本地仓库在IDEA中使用Maven创建一个普通的Maven项目在IDEA中标记文件夹功能在IDEA中配置tomcatpom文件IDEA操作解决遇到的问题Maven 为什么要学这个技术&#xff1f; 在javaweb…

P3242 [HNOI2015] 接水果(整体二分、扫描线、dfs序)

解析 一道有点毒瘤的题 也是一道感觉真的可以出现在考场上的很综合的题 做的还可以 除了一开始把盘子和水果看反白写了各树套树之外 为什么盘子是水果的子路径啊 由于是做专题爬过来的多次询问区间第k小&#xff0c;想到整体二分 那么重点就是子路径的判定问题 发现&#xff…

UOJ#748-[UNR #6]机器人表演【dp】

正题 题目链接:https://uoj.ac/problem/748 题目大意 有一个长度为nnn的010101序列&#xff0c;然后ttt次插入一个000和一个111&#xff0c;要求000在111前面&#xff0c;求最终能得到多少种本质不同的串。 1≤n,t≤3001\leq n,t\leq 3001≤n,t≤300 解题思路 我们考虑一个n…