Gym - 101667H:https://vjudge.net/problem/Gym-101667H

参考:https://blog.csdn.net/weixin_37517391/article/details/80154299

题意:

    已知两个人出剪刀石头布的顺序,第二个人可以选择从第一个人的任意手开始正式比赛,问第二个人赢得个数最多是多少。

思路:

    首先肯定要把第二个人所代表的字符串T转化为对应能赢的字符串rT。这时候暴力的话就是把rT拿去和第一个人的字符串匹配。

这里就可以用FFT优化了,FFT的作用就是求两个函数的卷积,令T’为rT的对称,我们试着做一下两个多项式相乘,可以发现新的卷积序列中的第k个位置的值等于S[k−lenT+1, k]与T‘序列对应位置乘积之和,所以构造两个函数,每个函数中,若这个位子有对应的字符,就为1,否则为0,利用FFT,就可以求出区间中某个字符匹配的个数。由于我们有三个字符,所以要做三次。

#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <complex>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> using namespace std;
//#pragma GCC optimize(3)
//#pragma comment(linker, "/STACK:102400000,102400000") //c++
// #pragma GCC diagnostic error "-std=c++11"
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3) #define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull; typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;
typedef complex<double> cp;
//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
#define REP(i , j , k) for(int i = j ; i < k ; ++i)
#define max3(a,b,c) max(max(a,b), c);
//priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
// const int mod = 10007;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /*-----------------------showtime----------------------*/
const int maxn = 1e5+; //注意不能和len1+len2的和刚刚好,因为n是最近的2的阶乘
// cp a[maxn<<2], b[maxn<<2], omg[maxn<<2], inv[maxn<<2];
int n = ; cp wn,wntmp;
void rader(cp arr[],int n){
int num = n-;
for(int i = ;i < n;++i){
int tn = n>>;
while(num && num >= tn) num ^= tn,tn >>= ;
num |= tn;
if(num > i) swap(arr[i],arr[num]);
}
}
void FFT(cp cs[],int n,int f){
rader(cs,n);
for(int s = ;s < n;s <<= ){
wn = cp(cos(f**PI/(s*)),sin(f**PI/(s*)));
for(int offset = ;offset < n;offset += s<<){
wntmp = cp(1.0,0.0);
for(int i = ;i < s;++i){
cp u = cs[offset+i],v = cs[offset+i+s]*wntmp;
cs[offset+i] = u + v;
cs[offset+i+s] = u - v;
wntmp = wntmp * wn;
}
}
}
if(f == -)
for(int i = ;i < n;++i)
cs[i].real(cs[i].real()/n);
} int len1,len2,ans[maxn<<];
char s1[maxn],s2[maxn];
cp a[maxn<<], b[maxn<<];
void solve(char c){
memset(a,,sizeof(a));
memset(b,,sizeof(b));
for(int i=; i<len1; i++) if(s1[i] == c) a[i] = cp(1.0);
for(int i=; i<len2; i++) if(s2[i] == c) b[i] = cp(1.0);
n=;
while(n < len1) n<<=;
n<<=;
FFT(a,n,);FFT(b,n,);
for(int i=; i<n; i++)a[i] = a[i] * b[i];
FFT(a,n,-);
for(int i=len2-; i<n; i++){
ans[i] += int(a[i].real() + 0.5);
}
}
int main(){ scanf("%d%d%s%s", &len1, &len2, s1,s2);
int le = ,ri = len2-;
while(le <= ri) swap(s2[le],s2[ri]),le++,ri--;
// cout<<s2<<endl;
for(int i=; i<len2; i++){
if(s2[i] == 'S')s2[i] = 'P';
else if(s2[i] == 'R')s2[i] = 'S';
else s2[i] = 'R';
}
solve('R'),solve('S'),solve('P');
int mx = ;
for(int i=; i<=len1+len2; i++) mx = max(mx, ans[i]);
printf("%d\n", mx);
return ;
}

Gym-101667H

Gym - 101667H - Rock Paper Scissors FFT 求区间相同个数的更多相关文章

  1. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)

    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...

  2. 洛谷 P1865 A % B Problem(求区间质数个数)

    题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对 ...

  3. LightOj 1197 - Help Hanzo(分段筛选法 求区间素数个数)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1197 题意:给你两个数 a b,求区间 [a, b]内素数的个数, a and b ( ...

  4. FFT(Rock Paper Scissors Gym - 101667H)

    题目链接:https://vjudge.net/problem/Gym-101667H 题目大意:首先给你两个字符串,R代表石头,P代表布,S代表剪刀,第一个字符串代表第一个人每一次出的类型,第二个字 ...

  5. Gym101667 H. Rock Paper Scissors

    将第二个字符串改成能赢对方时对方的字符并倒序后,字符串匹配就是卷积的过程. 那么就枚举字符做三次卷积即可. #include <bits/stdc++.h> struct Complex ...

  6. SDUT 3568 Rock Paper Scissors 状压统计

    就是改成把一个字符串改成三进制状压,然后分成前5位,后5位统计, 然后直接统计 f[i][j][k]代表,后5局状压为k的,前5局比和j状态比输了5局的有多少个人 复杂度是O(T*30000*25*m ...

  7. 【题解】CF1426E Rock, Paper, Scissors

    题目戳我 \(\text{Solution:}\) 考虑第二问,赢的局数最小,即输和平的局数最多. 考虑网络流,\(1,2,3\)表示\(Alice\)选择的三种可能性,\(4,5,6\)同理. 它们 ...

  8. 题解 CF1426E - Rock, Paper, Scissors

    一眼题. 第一问很简单吧,就是每个 \(\tt Alice\) 能赢的都尽量让他赢. 第二问很简单吧,就是让 \(\tt Alice\) 输的或平局的尽量多,于是跑个网络最大流.\(1 - 3\) 的 ...

  9. HDOJ(HDU) 2164 Rock, Paper, or Scissors?

    Problem Description Rock, Paper, Scissors is a two player game, where each player simultaneously cho ...

随机推荐

  1. VM虚拟机Linux系统eth0下面没有inet和inet6

    今天打开虚拟机发现ip有问题,VM虚拟机Linux系统eth0下面没有inet和inet6,明明都是配置好的 打开任务管理器-> 服务-> 打开VM的nat和DHCP和hostd 正常后:

  2. python利用select实现的Socket Server

    # 利用python的select模块实现简单的Socket Sever #实现多用户访问,再次基础上可以实现FTP Server应用程序 # 发布目的,在于解决了客户端强行终止时,服务器端也跟着程序 ...

  3. hdoj 4762 Cut the Cake

    题意很简单就不说了. 解题的关键就是这个公式 answer=n/(m^(n-1)); 要用到大数的乘法.然后java水过. import java.util.*; import java.math.* ...

  4. oracle的本地远程连接和配置

    Oracle数据库的远程连接可以通过多种方式来实现,本文我们主要介绍四种远程连接的方法和注意事项,并通过示例来说明,接下来我们就开始介绍. 第一种情况: 若oracle服务器装在本机上,那就不多说了, ...

  5. 一文了解:Redis的RDB持久化

    一文了解:Redis的RDB持久化 Redis是内存数据库,为了保证数据不在故障后丢失,Redis需要将数据持久化到硬盘上. Redis持久化有两种方式:一种是快照,全量备份.一种是AOF方式,连续增 ...

  6. 【作品】超实用C++分数类

    引言 我们说,编程语言的精髓在于封装,而面向对象语言完胜面向过程语言的原因就是具有更好的可封装性,而C++就是这样的一种多范型语言,常用而复杂的工作完全不必在每一份源文件中重敲,就好像我们不需要自己手 ...

  7. 多态、继承、this、super

    先放一下多态的定义: (360词典上的哈) 多态(Polymorphism)按字面的意思就是"多种状态".在面向对象语言中,接口的多种不同的实现方式即为多态.引用Charlie C ...

  8. 章节十五、8-配置文件File Logging

    一.如何将log输出到文件中? 1.配置xml文件 <?xml version="1.0" encoding="UTF-8"?> <Confi ...

  9. tensorflow学习笔记——图像数据处理

    喜欢摄影的盆友都知道图像的亮度,对比度等属性对图像的影响是非常大的,相同物体在不同亮度,对比度下差别非常大.然而在很多图像识别问题中,这些因素都不应该影响最后的结果.所以本文将学习如何对图像数据进行预 ...

  10. Microsoft Access数据库操作类(C#)

    博文介绍的Microsoft Access数据库操作类是C#语言的,可实现对Microsoft Access数据库的增删改查询等操作.并且该操作类可实现对图片的存储,博文的最后附上如何将Image图片 ...