编辑字符串(edit)

初见感觉像贪心,但在不好写+不会证的情况下放弃了,然后想到DP又设不出状态。

实际上……就是贪心哦?


下文称\(s_1,s_2\)分别为\(a,b\)。

不难发现一个不存在锁定位置的区间,其内元素是可以任意交换的。

所以我们可以按照锁定位置,将两个字符串划分成若干个区间(被锁定的位置可以看作单独的一个区间)。

贪心的思路,就是一个指针\(i\)从头开始遍历,不断取\(a_i,b_i\)所在的区间,如果两个区间都存在未被匹配的\(0\),就用\(0\)进行匹配,否则如果存在未被匹配的\(1\),就用\(1\)匹配。

正确性仔细一想其实比较显然。

我们各取\(a,b\)最左边的区间\(A\)和\(B\)(显然它们是左端对齐的),假设\(|A|\ge |B|\)。

按贪心对两个区间进行匹配后,如果将\(A\)长度为\(|B|\)的前缀中任选一个元素交换到此前缀之后:

  • 如果交换出去后,该前缀对答案的贡献\(-1\):因为交换出去的那个元素最多能产生\(+1\)的贡献,所以最好情况下也只能使答案不变。
  • 如果交换出去后,该前缀对答案的贡献不变:说明交换的两个值相等,所以答案不变。
  • 如果交换出去后,该前缀对答案的贡献\(+1\):根据贪心的过程,一定不存在这种情况。
点击查看代码
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int t,n,pa[N],pb[N],ca[N][2],cb[N][2],ans;
string a,b,c,d;
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
cin>>t;
while(t--){
memset(ca,0,sizeof ca);
memset(cb,0,sizeof cb);
cin>>n>>a>>b>>c>>d;
for(int i=0,p=0;i<n;i++){
if(c[i]&1) pa[i]=((~p)?p:(p=i));
else pa[i]=i,p=-1;
}
for(int i=0,p=0;i<n;i++){
if(d[i]&1) pb[i]=((~p)?p:(p=i));
else pb[i]=i,p=-1;
}
for(int i=0;i<n;i++)
ca[pa[i]][a[i]&1]++,cb[pb[i]][b[i]&1]++;
ans=0;
for(int i=0;i<n;i++){
if(ca[pa[i]][0]&&cb[pb[i]][0])
ans++,ca[pa[i]][0]--,cb[pb[i]][0]--;
else if(ca[pa[i]][1]&&cb[pb[i]][1])
ans++,ca[pa[i]][1]--,cb[pb[i]][1]--;
}
cout<<ans<<"\n";
}
return 0;
}

遗失的赋值(assign)

如果给定的一元关系本就存在矛盾,特判输出\(0\)即可。我们只分析一元关系不存在矛盾的情况。

一种二元关系的构造是不合法的,当且仅当存在二元关系区间\([l,r)\),满足:

  • \(x_l,x_r\)的值均是一元关系给定的;
  • \(a_l=x_l\);
  • 对于\(i\in(l,r)\),都有\(a_i=b_{i-1}\);
  • \(b_{r-1}\ne x_r\)。

进一步我们发现,将第\(1\)条(条件A)替换成“\([l,r]\)中 仅有 \(x_l,x_r\)的值是一元关系给定的”(条件B),这样判定仍然是正确的。因为每一个满足条件A的不合法的大区间\([l,r]\),都包含同样满足条件B的不合法的小区间\([l',r']\)。

比如下图,红色线段是二元限制,绿点是一元限制。\([12,16)\)这个满足条件A的不合法区间,就包含\([14,16)\)这个满足条件B的不合法区间。

所以我们可以将一元关系从小到大排序,依次考虑相邻的一元关系之间,合法的构造个数,用乘法原理计算答案即可。

对于\(x_l,x_r\)两个相邻的一元关系,它们之间合法的构造个数就是总个数\(-\)不合法的构造个数。

  • \(l,r\)之间有\(r-l\)个二元关系,每个二元关系有\(2\)个值,所以总个数是\(v^{2(r-l)}\)。
  • 根据上面的判定条件,我们要让\([l,r)\)之间的二元关系连成一条链,其中左端点只能选\(x_l\),中间的点都可以随便选择,右端点可以选除了\(x_r\)以外的任何值。所以不合法的构造数是\(v^{r-l-1}\times (v-1)\)。

相减,得到\(v^{2(r-l)}-v^{r-l-1}\times (v-1)\)。用所有\(l,r\)的答案累乘起来就可以了(所以答案其实是和\(d\)无关的)。

注意,还需要额外累乘最左边和最右边的答案,显然这两处都可以随便构造,所以直接累乘合法的数量即可。

每组测试数据\(O(m(\log m+\log n))\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define mod 1000000007
#define M 100010
using namespace std;
struct Limit{int c,d;}lim[M];
int t,n,m,v;
int qpow(int a,int n){
int ans=1;
while(n){
if(n&1) ans=ans*a%mod;
a=a*a%mod,n>>=1;
}
return ans;
}
int solve(){
sort(lim+1,lim+1+m,[](Limit a,Limit b){return a.c<b.c;});
for(int i=1;i<m;i++)
if(lim[i].c==lim[i+1].c&&lim[i].d!=lim[i+1].d) return 0;
int ans=1;
for(int i=1;i<m;i++){
int l=lim[i].c,r=lim[i+1].c;
if(l==r) continue;
ans=ans*((qpow(v,(r-l)<<1)-qpow(v,r-l-1)*(v-1))%mod+mod)%mod;
}
ans=ans*qpow(v,(lim[1].c-1)<<1)%mod;
ans=ans*qpow(v,(n-lim[m].c)<<1)%mod;
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
cin>>t;
while(t--){
cin>>n>>m>>v;
for(int i=1;i<=m;i++) cin>>lim[i].c>>lim[i].d;
cout<<solve()<<"\n";
}
return 0;
}

树的遍历(traverse)

我们将边看作点,构建一个新图。新图上的两点之间有边,当且仅当它们对应原图上的两边有公共顶点。这样构建出的图称为原图的线图,这道题就是指定了线图上的若干个关键点,让我们求出从这些关键点开始遍历能得到的DFS树的形态数。

\(k=1\)的情况比较送,因为不难发现原图上某点的邻接边,在线图上构成了一个团(完全子图)。一个完全图的DFS树是一条链,由于原图是一棵树,所以指定DFS树的根节点后,每个团第一个被遍历到的点是确定的,而其他点顺序任意。所以答案是\(\prod\limits_{u\in {V}} (deg_u-1)!\),其中\(V\)是原图上的点集,\(deg_u\)是\(u\)的度数。

正解之后补。

[题解]NOIP 2024 T1~T2的更多相关文章

  1. Action<T1, T2>委托

    封装包含两个参数的方法委托,没有返回值. 语法 public delegate void Action<in T1, in T2>( T1 arg1, T2 arg2 ) 类型参数 in ...

  2. DateTime.Compare(t1,t2)比較两个日期大小

    DateTime.Compare(t1,t2)比較两个日期大小,排前面的小,排在后面的大,比方:2011-2-1就小于2012-3-2返回值小于零:  t1 小于 t2. 返回值等于零 : t1 等于 ...

  3. 使用Func<T1, T2, TResult>

    使用Func<T1, T2, TResult> 委托返回匿名对象   Func<T1, T2, TResult> 委托 封装一个具有两个参数并返回 TResult 参数指定的类 ...

  4. java 多线程,T1 T2 T3 顺序执行

    一.程序设计 1.抽象公共类PublicThread,具有先前线程属性previousThread.父类为Thread 2.在PublicThread的run()方法中判断previousThread ...

  5. 三个线程T1,T2,T3.保证顺序执行的三种方法

    经常看见面试题:有三个线程T1,T2,T3,有什么方法可以确保它们按顺序执行.今天手写测试了一下,下面贴出目前想到的3种实现方式 说明:这里在线程中我都用到了sleep方法,目的是更容易发现问题.之前 ...

  6. C# Tuple<T1,T2....T>元组的使用

    1) 先说组元:一个数据结构,由通过逗号分割的,用于传递给一个程序或者操作系统的一系列值的组合. NET Framework 直接支持一至七元素的元组 Tuple<T1> Tuple< ...

  7. DateTime.Compare(t1,t2)比较两个日期大小

    DateTime.Compare(t1,t2)比较两个日期大小,排前面的小,排在后面的大,比如:2011-2-1就小于2012-3-2返回值小于零:  t1 小于 t2. 返回值等于零 : t1 等于 ...

  8. Func<T1, T2, TResult> Delegate 系统Func委托类型

    原文发布时间为:2011-03-25 -- 来源于本人的百度文章 [由搬家工具导入] http://msdn.microsoft.com/en-us/library/bb534647%28v=VS.1 ...

  9. 对复杂字典Dictionary<T1,T2>排序问题

    原文:对复杂字典Dictionary<T1,T2>排序问题 //VoltageCount类(电压值对应的数量):    public class VoltageCount    {     ...

  10. 使用Func<T1, T2, TResult> 委托返回匿名对象

    Func<T1, T2, TResult> 委托 封装一个具有两个参数并返回 TResult 参数指定的类型值的方法. 语法 public delegate TResult Func< ...

随机推荐

  1. Prometheus配置文件详解

    概述 Prometheus是一个开源的系统监控和警报工具包.它的配置文件通常命名为prometheus.yml,用于配置Prometheus服务器的行为. 其配置文件主要包含以下几个部分: globa ...

  2. Pod原理以及Pod生命周期

    一.Pod的介绍 1.为什么需要Pod? 假设 Kubernetes 中调度的基本单元就是容器,对于一个非常简单的应用可以直接被调度直接使用,没有什么问题,但是往往还有很多应用程序是由多个进程组成的, ...

  3. Go中的文件操作

    文件操作 读取文件的内容并显示在终端(带缓冲区的方式),使用os.Open,file.Close,bufio.NewReader(),reader.ReadString函数和方法. package m ...

  4. Ceph对象存储集群常用操作

    一.常用操作 1.1 查看某个bucket详情 # 查看bucket列表 [root@oss001 ~]# radosgw-admin bucket list [ "awss3e68c588 ...

  5. 给Markdown渲染网页增加一个目录组件(Vite+Vditor+Handlebars)(下)

    1 引言 在上一篇文章<给Markdown渲染网页增加一个目录组件(Vite+Vditor+Handlebars)(上)>中笔者介绍了如何实现在Markdown渲染网页中加一个目录组件.不 ...

  6. 数栈技术分享:前端小姐姐和你聊聊IOC中依赖注入那些事 (Dependency inject)

    ​ Part1: What is Dependency injection 依赖注入定义为组件之间依赖关系由容器在运行期决定,形象的说即由容器动态的将某个依赖关系注入到组件之中在面向对象编程中,我们经 ...

  7. 在使用Flink CDC时,源表没有主键如何处理

    本文分享自天翼云开发者社区<在使用Flink CDC时,源表没有主键如何处理>,作者:5****m 在Flink CDC中,当源表没有主键时,需要设置scan.incremental.sn ...

  8. C#_DateTime转换成Unix时间戳方法

    /// <summary> /// DateTime时间格式转换为Unix时间戳格式 /// </summary> /// <param name="time& ...

  9. stm32 单片机主要优点有哪些?

    STM32单片机主要优点有哪些?一个十年嵌入式老兵的深度剖析 看到这个问题,我不禁想起了十年前那个拿着STM32开发板发愁的自己.作为一个本硕都是机械专业,却误打误撞进入嵌入式领域的过来人,从24岁在 ...

  10. CF1946C Tree Cutting 题解

    CF1946C Tree Cutting 容易发现,如果连通块含有节点数的最小值为 \(x\),并且使用的刀数多于或等于 \(k\),那么 \(x\) 一定可以成为最后的结果.原因是我们可以通过减少一 ...