[Comet1790]Ternary String Counting
令$f_{i,j,k}$表示前$i$个位置,三种字符最后一次出现的位置为$i,j$和$k$(保证$k<j<i$)的方案数
考虑转移(递推),即分为两步——
1.填写第$i$个字符,即从$f_{i-1,j,k}$转移到$f_{i,j,k},f_{i,i-1,j}$或$f_{i,i-1,k}$
2.考虑以$i$为右端点的区间,即仅保留$j\in [L_{j}(i),R_{j}(i)]$且$k\in [L_{k}(i),R_{k}(i)]$的位置(其余位置清0)
(关于$L/R_{j/k}(i)$显然可以$o(m)$预处理出)
暴力转移复杂度为$o(n^{3})$,考虑优化——
关于第一步,如果将$i$滚动,实际上修改的位置仅有$o(n)$个,而修改的值即某行/列的元素和,那么再额外维护该信息,同时修改也可以继续维护,复杂度降为$o(n^{2})$
关于第二步,注意到一个位置被清0后不会再有值,那么只需要快速找到需要清0且非0的位置,这可以对每行维护一个双向队列来实现,进而均摊复杂度也降为$o(n^{2})$
最终,总复杂度为$o(n^{2}+m)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 5005
4 #define mod 1000000007
5 deque<int>q[N];
6 int t,n,m,l,r,x,ans,Lj[N],Rj[N],Lk[N],Rk[N],sr[N],sc[N],f[N][N];
7 int read(){
8 int x=0;
9 char c=getchar();
10 while ((c<'0')||(c>'9'))c=getchar();
11 while ((c>='0')&&(c<='9')){
12 x=x*10+c-'0';
13 c=getchar();
14 }
15 return x;
16 }
17 void upd(int x,int y,int z){
18 q[y].push_back(x);
19 sr[x]=(sr[x]+z)%mod;
20 sc[y]=(sc[y]+z)%mod;
21 f[x][y]=(f[x][y]+z)%mod;
22 }
23 void clear_l(int y){
24 int x=q[y].front();
25 q[y].pop_front();
26 sr[x]=(sr[x]-f[x][y]+mod)%mod;
27 sc[y]=(sc[y]-f[x][y]+mod)%mod;
28 f[x][y]=0;
29 }
30 void clear_r(int y){
31 int x=q[y].back();
32 q[y].pop_back();
33 sr[x]=(sr[x]-f[x][y]+mod)%mod;
34 sc[y]=(sc[y]-f[x][y]+mod)%mod;
35 f[x][y]=0;
36 }
37 int main(){
38 t=read();
39 while (t--){
40 n=read(),m=read();
41 for(int i=1;i<=n;i++){
42 Lj[i]=Lk[i]=0;
43 Rj[i]=Rk[i]=i-1;
44 }
45 for(int i=1;i<=m;i++){
46 l=read(),r=read(),x=read();
47 if (x==1)Rj[r]=min(Rj[r],l-1);
48 if (x==2)Lj[r]=max(Lj[r],l),Rk[r]=min(Rk[r],l-1);
49 if (x==3)Lk[r]=max(Lk[r],l);
50 }
51 memset(sr,0,sizeof(sr));
52 memset(sc,0,sizeof(sc));
53 memset(f,0,sizeof(f));
54 for(int i=0;i<n;i++)q[i].clear();
55 upd(0,0,1);
56 for(int i=1;i<=n;i++){
57 for(int j=0;j<max(i-1,1);j++)upd(i-1,j,(sr[j]+sc[j])%mod);
58 for(int j=0;j<i;j++){
59 if ((Lk[i]<=j)&&(j<=Rk[i])){
60 while ((!q[j].empty())&&(q[j].front()<Lj[i]))clear_l(j);
61 while ((!q[j].empty())&&(q[j].back()>Rj[i]))clear_r(j);
62 }
63 else{
64 while (!q[j].empty())clear_l(j);
65 }
66 }
67 }
68 ans=0;
69 for(int i=0;i<n;i++)
70 for(int j=0;j<n;j++)ans=(ans+f[i][j])%mod;
71 printf("%d\n",ans);
72 }
73 return 0;
74 }
[Comet1790]Ternary String Counting的更多相关文章
- Balanced Ternary String CodeForces - 1102D (贪心+思维)
You are given a string ss consisting of exactly nn characters, and each character is either '0', '1' ...
- 牛客多校第四场 A Ternary String
题目描述 A ternary string is a sequence of digits, where each digit is either 0, 1, or 2. Chiaki has a t ...
- 2018牛客网暑期ACM多校训练营(第四场) A - Ternary String - [欧拉降幂公式][扩展欧拉定理]
题目链接:https://www.nowcoder.com/acm/contest/142/A 题目描述 A ternary string is a sequence of digits, where ...
- CodeForces - 1009B Minimum Ternary String
You are given a ternary string (it is a string which consists only of characters '0', '1' and '2'). ...
- 牛客网暑期ACM多校训练营(第四场):A Ternary String(欧拉降幂)
链接:牛客网暑期ACM多校训练营(第四场):A Ternary String 题意:给出一段数列 s,只包含 0.1.2 三种数.每秒在每个 2 后面会插入一个 1 ,每个 1 后面会插入一个 0,之 ...
- B. Minimum Ternary String (这个B有点狠)
B. Minimum Ternary String time limit per test 1 second memory limit per test 256 megabytes input sta ...
- codeforces ~ 1009 B Minimum Ternary String(超级恶心的思维题
http://codeforces.com/problemset/problem/1009/B B. Minimum Ternary String time limit per test 1 seco ...
- CF1009B Minimum Ternary String 思维
Minimum Ternary String time limit per test 1 second memory limit per test 256 megabytes input standa ...
- Balanced Ternary String(贪心+思维)
题目链接:Balanced Ternary String 题目大意:给一个字符串,这个字符串只由0,1,2构成,然后让替换字符,使得在替换字符次数最少的前提下,使新获得的字符串中0,1,2 这三个字符 ...
随机推荐
- 全套Java教程_Java基础入门教程,零基础小白自学Java必备教程 #011 # 第十一单元 String&ArrayList #
一.本单元知识点概述 (Ⅰ)知识点概述 二.本单元教学目标 (Ⅰ)重点知识目标 1.ArrayList集合的常用方法2.ArrayList存储数据和遍历数据3.String类的构造方法4.String ...
- break和continue关键字
什么是break break 跳出最里层的循环,并且继续执行该循环下面的语句 就是强制退出循环 示例 package struct; public class ForDemo05 { public s ...
- WinForm事件与消息
WinForm事件与消息 消息概述以及在C#下的封装 Windows下应用程序的执行是通过消息驱动的.所有的外部事件,如键盘输入.鼠标移动.按动鼠标都由OS系统转换成相应的"消息" ...
- SQL SERVER数据库权限分配
1,新建 只能访问某一个表的只读用户. --添加只允许访问指定表的用户: exec sp_addlogin '用户名','密码','默认数据库名' ...
- Redis 面试常见问题———缓存雪崩、缓存击穿以及缓存穿透
在开发中会面临缓存异常可能会出现三个问题,分别是缓存雪崩.缓存击穿和缓存穿透.这三个问题会导致大量请求从缓存转移到数据库,如果请求的并发量很大的话,就会导致数据库崩溃.所以在面试官也会经常问这些问题. ...
- FastAPI 学习之路(十五)响应状态码
系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...
- Java(15)面向对象之继承
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201615.html 博客主页:https://www.cnblogs.com/testero ...
- shell关键字含义
linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行 ...
- 【c++ Prime 学习笔记】第17章 标准库特殊设施
17.1 tuple类型 tuple是类似pair的模板: pair和tuple的成员类型都可以不相同 pair恰好有两个成员,tuple可有任意数量的成员 按照不同参数数量和类型实例化出的tuple ...
- 软件案例分析——VS、VS Code
软件案例分析--VS和VS Code 第一部分 调研,测评 一.使用10–30分钟这个软件的基本功能(请上传使用软件的照片) VS code Visual Studio 二.主要功能和目标用户有何不同 ...