K-Inversions
Problem Description
You are given a string s consisting only of upper case letters A and B. For an integer k, a pair of indices i and j (1 ≤ i < j ≤ n) is called a k-inversion if and only if s[i] = B, s[j] = A and j − i = k.
Consider the string BABA. It has two 1-inversions and one 3-inversion. It has no 2-inversions.
For each k between 1 and n − 1 (inclusive), print the number of k-inversions in the string s.
Input
Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. The input will consist of a single line with a string s, which consists of only upper case As and Bs. The string s will be between 1 and 1,000,000 characters long. There will be no spaces
Output
Output n − 1 lines, each with a single integer. The first line’s integer should be the number of 1-inversions, the second should be the number of 2-inversions, and so on.
SampleInput
BABA
Sample Output
2
0
1
Solve:
这个题就是求对于每个x,有多少AB之间相差x(A 在 B后面)
暴力的话,可以枚举每一个A和每一个B,求两者之间的距离为x,ans[x]++,但是这样肯定会超时的
那么想想多项式乘法,假如有两个多项式,那么他们的每一项系数都要互相乘,相乘时候具有相同的指数的系数加起来,那么他们的指数也是相加的
而这个题,把每个A的下标看成第一个式子的指数,系数都为1,B的下标看成第二个式子的指数,系数为1,那么这里是,指数相减之后相同的系数相乘求和
醉了,描述不清
那么我已经有了一个串比如BABA,定义两个数组
那么从左向右,如果扫到了A那么第一个数组相应的值为1
如果扫到了B,那么第二个数组倒着相应的值为0
所以第一个数组为0101
第二个数组为0101,把这两个串看成十进制的数字
那么这样的话,如果某个B出现在i位置上,A出现在j位置上,那么这两个位置对应的数组表示分别为1*10i,1*10n-j-1,那么这两位相乘之后得到的值为10n-j-1+i =10x,那么j-i=x+1-n也就是j和i之间相差几个,那么两个数字相乘就得到了所有的x
其中因为求的是相差1~n的有几个 ,所以1<=x-1+n<=n ===> 0<=x<=n-2
所以应该输出最低位的n-1个,就是答案的(n~2n-1)位
所以就用FFT。。。。。。。
代码:
//https://open.kattis.com/problems/kinversions.cpp
#include
using namespace std;
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
typedef complex
base;
void fft(vector
&a, bool invert)
{
int n = a.size();
for (int i=1,j=0; i
> 1;
for (; j>=bit; bit>>=1) j -= bit;
j += bit;
if (i < j) swap(a[i],a[j]);
}
for (int len=2; len<=n; len<<=1)
{
double ang = 2*M_PI/len*(invert?-1:1);
base wlen(cos(ang),sin(ang));
for (int i=0; i
&a,const vector
&b,vector
&res) { vector
fa(a.begin(),a.end()), fb(b.begin(),b.end()); int n = 1; while (n < max(a.size(),b.size())) n <<= 1; n <<= 1; fa.resize(n); fb.resize(n); fft(fa,false); fft(fb,false); for (int i=0; i
0?0.5:-0.5)); } char t[1000001]; int main() { // freopen("in.txt","r",stdin); vector
a, b, r; int i, n; scanf("%s", t); for (n = 0; t[n]; n++); a.resize(n); b.resize(n); for (i = 0; i < n; i++) { if (t[i] == 'A') a[i] = 1; else b[n - i - 1] = 1; } multiply(a, b, r); for (i = 0; i < n * 2 - 1; i++) printf("%d\n", r[i]); }