首页 > 其他分享 > CF1383E Strange Operation 题解

CF1383E Strange Operation 题解

时间:2022-11-21 08:44:06浏览次数:87  
标签:return int 题解 void lst Strange MAXN str Operation

link

Solution

shaber 题,但是又没有做出来。

我们发现这个变化相当于可以任意删掉 \(0\),\(1\) 的话只有与 \(1\) 相邻的时候可以删掉。那么相当于我们可以把一段包含 \(1\) 的段变成只包含 \(1\) 的段。

既然要对本质不同的变化串计数,那么我们可以考虑建 DFA。加 \(1\) 的话直接找后面第 \(1\) 个 \(1\) 即可。加 \(0\) 的话如果当前为 \(1\) 或者下一个就是 \(0\) 的话我们直接找下一个 \(0\) 即可。那么需要考虑的就是当前为一段连续 \(0\) 的结尾,要加 \(1\) 个 \(0\),那么我们就需要找到后面第一个 \(0\) 连续段大于当前连续段长度的当前连续短长度个 \(0\) 的下一位。因为你可以把中间的 \(1\) 跟 \(0\) 接在前面的 \(1\) 连续段之后,然后删掉,那么你就需要再取若干个 \(0\)。这个直接用个单调栈维护一下就好了。

那么相当于我们从 \(1\) 出发,再到任意一个 \(1\) 结尾即可,因为后面的部分全都可以删掉。

Code

#include <bits/stdc++.h>
using namespace std;
     
#define Int register int
#define mod 1000000007
#define MAXN 1000005

// char buf[1<<21],*p1=buf,*p2=buf;
// #define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}

char str[MAXN];int n,m,f[MAXN],g[MAXN][2];

int mul (int a,int b){return 1ll * a * b % mod;}
int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
int qkpow (int a,int b){
	int res = 1;for (;b;b >>= 1,a = mul (a,a)) if (b & 1) res = mul (res,a);
	return res;
}
void Add (int &a,int b){a = add (a,b);}
void Sub (int &a,int b){a = dec (a,b);}

int top,sta[MAXN],len[MAXN],edp[MAXN];

signed main(){
	scanf ("%s",str + 1),n = strlen (str + 1);
	int L = 1;while (str[L] == '0') ++ L;
	int R = n;while (str[R] == '0') -- R;
	if (L > R){write (n),putchar ('\n');return 0;}
	for (Int x = R,lst = 0;x >= L;-- x){
		g[x][1] = lst;
		if (str[x] == '1') lst = x;
	}
	for (Int x = R,lst = 0;x >= L;-- x){
		if (str[x] == '1' || str[x + 1] == '0') g[x][0] = lst;
		if (str[x] == '0') lst = x;
	}
	for (Int x = L,sum = 0;x <= R;++ x){
		if (str[x] == '0'){
			sum ++;
			while (top && len[top] < sum) g[edp[top --]][0] = x;
		}
		else ++ top,len[top] = sum,edp[top] = x - 1,sum = 0;
	}
	f[L] = 1;int ans = 0;
	for (Int x = L;x <= R;++ x){
		if (str[x] == '1') Add (ans,f[x]);
		for (Int t = 0;t < 2;++ t) if (g[x][t]) Add (f[g[x][t]],f[x]);
	}
	write (mul (mul (L,n - R + 1),ans)),putchar ('\n');
	return 0;
}

标签:return,int,题解,void,lst,Strange,MAXN,str,Operation
From: https://www.cnblogs.com/Dark-Romance/p/16910283.html

相关文章

  • [题解] Uoj Easy Round 11
    A使用动态规划,\(f_{i,j}\)代表竖着的前\(i\)个,第\(i\)个被第\(j\)个横着的挡住的方案数,当然前提是有\(l_j\gei\),否则\(f_{i,j}=0\)。转移就是做一遍前缀和。考......
  • ABC245G题解
    似乎是经典套路?先不考虑颜色限制,那么就直接把\(l\)个关键点当作起点跑多源最短路就行了。现在考虑颜色限制,有一种暴力的想法是枚举所有颜色,只把这种颜色的点当作起点,然......
  • Codeforces 1740 F Conditional Mix 题解
    题目链接对于任意一个multiset,我们都把它的元素从大到小排序来观察。发现一个multiset合法有个必要条件:对于每个i,multiset中最大的i个元素之和不能超过\(lim_i\),如果令\(c......
  • 2022/11/20 集训题解 Longest Loose Segment
    linkDescription定义\(a_{1,2,...,m}\)为好序列当且仅当\(\maxa_i+\mina_i>m\),给出一个长度为\(n\)的序列,问最长好序列子段长度。有\(T\)次修改。\(n\le10^6,......
  • P4047 [JSOI2010]部落划分 题解
    最小生成树做法之Kruskal算法流程(详细分析请看代码注释):1.初始化并查集并查集模板不过多解释,还不懂请参阅并查集-OIWiki。每个节点的祖先最开始都是自己。还有......
  • U255813 争宠题解
    题目传送门#include<bits/stdc++.h>usingnamespacestd;voidjia(strings1,strings2){boolaaa=0;inta[5010],b[5010],c[5010];memset(a,0,sizeof(......
  • 《Consequentialist Conditional Cooperation in Social Dilemmas with Imperfect Inf
    环境:Fishery:湖两岸有两个钓鱼人互相观察不到对方的动作,湖里有幼鱼和成熟鱼奖励分别为1和2,鱼游到对岸变成成熟鱼。合作方案即将幼鱼放给对岸,背叛即被诱惑吊幼鱼。PongPl......
  • AtCoder Beginner Contest 278题解
    A-Shift题意给一个长度为\(n\)的数组,有\(k\)次操作,每次操作会将数组最前面的元素删掉,再在数组最后面加上一个0元素,问\(k\)次操作后的数组中的数字。思路看\(n\)与\(k......
  • Codeforces 704 B Antman 题解 (dp,贪心,结论)
    题目链接这题两种不同做法,普通的\(O(n^2)\)和奇怪的\(O(nlogn)\)。如果用\(O(nlogn)\)的话可以加强到1e6。做法1时间复杂度\(O(n^2)\)先把最终的排列随便画一个出来观......
  • C. Sum of Substrings题解
    C.SumofSubstrings题目大概意思,给你一个01串,求和最小,其中和是该串所有相邻字符所组成的十进制数的和。如:0110,sum=01+11+10=22。通过观察我们可以发现,除了第......