Tuesday, 5 January 2016

A. Substring and Subsequence
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
One day Polycarpus got hold of two non-empty strings s and t, consisting of lowercase Latin letters. Polycarpus is quite good with strings, so he immediately wondered, how many different pairs of "x y" are there, such that x is a substring of string sy is a subsequence of string t, and the content of x and y is the same. Two pairs are considered different, if they contain different substrings of string s or different subsequences of string t. Read the whole statement to understand the definition of different substrings and subsequences.
The length of string s is the number of characters in it. If we denote the length of the string s as |s|, we can write the string ass = s1s2... s|s|.
substring of s is a non-empty string x = s[a... b] = sasa + 1... sb (1 ≤ a ≤ b ≤ |s|). For example, "code" and "force" are substrings or "codeforces", while "coders" is not. Two substrings s[a... b] and s[c... d] are considered to be different if a ≠ c or b ≠ d. For example, if s="codeforces", s[2...2] and s[6...6] are different, though their content is the same.
subsequence of s is a non-empty string y = s[p1p2... p|y|] = sp1sp2... sp|y| (1 ≤ p1 < p2 < ... < p|y| ≤ |s|). For example, "coders" is a subsequence of "codeforces". Two subsequences u = s[p1p2... p|u|] and v = s[q1q2... q|v|] are considered different if the sequencesp and q are different.
Input
The input consists of two lines. The first of them contains s (1 ≤ |s| ≤ 5000), and the second one contains t (1 ≤ |t| ≤ 5000). Both strings consist of lowercase Latin letters.
Output
Print a single number — the number of different pairs "x y" such that x is a substring of string sy is a subsequence of string t, and the content of x and y is the same. As the answer can be rather large, print it modulo 1000000007 (109 + 7).
Sample test(s)
input
aa
aa
output
5
input
codeforces
forceofcode
output
60
Note
Let's write down all pairs "x y" that form the answer in the first sample: "s[1...1] t[1]", "s[2...2] t[1]", "s[1...1] t[2]","s[2...2] t[2]", "s[1...2] t[1 2]".

The state of the dp is dp[i][j] , that stands for 
every subset in i to j of string s we try to find the number of subsequences in j to |t| of string t


the recurrence can be derived as f(i,j)=1+f(i+1,j+1) if s[i]==t[j]
                                       else f(i+1,j+1)
First go through the recusrsive code

   let us take two examples 
     
           s=abcd
           t=babc

      so first we have s[0]=a 
       Now we iterate j from 0 to |t| for occurence of a , as soon as we 
get one we call go(i+1,j+1) 

           here we have a pick or leave situation  
           where we add res=go(i,j+1)  that is we search everywhere for the same character
      after we have done for all the occurences we go to call go(i+1,j+1). 
int the example above after getting all occurences of a in the string t we move for occurences of b in string t 


Code goes here

#include <cstdio>
#include <numeric>
#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <queue>
#include <sstream>
#include <deque>

using namespace std;

#define mp make_pair
#define pb push_back
#define rep(i,n) for(int i = 0; i < (n); i++)
#define re return
#define fi first
#define se second
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
#define sqr(x) ((x) * (x))
#define sqrt(x) sqrt(abs(x))
#define y0 y3487465
#define y1 y8687969
#define fill(x,y) memset(x,y,sizeof(x))
                         
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef double D;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef vector<vi> vvi;

template<class T> T abs(T x) { re x > 0 ? x : -x; }

const int mod = 1000000000 + 7;

int n;
int m;

int was[5001][5001];
int res[5001][5001];
string s, t;

int go (int i, int j) {
    if (j == m) re 1;
    if (was[i][j]) re res[i][j];
    was[i][j] = 1;
    int cur = go (i, j + 1);  // here we are trying to find the occurences of the same character in string t
    if (s[i] == t[j]) cur = (cur + go (i + 1, j + 1)) % mod;    // here we are searching for s[i+1] 
    re res[i][j] = cur;                                        // in all positions of the string t hence
}                                                         //  go(i+1,j+1)

int main () {
    cin >> s >> t;
    n = sz (s);
    m = sz (t);
    int ans = 0;
    for (int i = 0; i < n; i++) 
        for (int j = 0; j < m; j++)
            if (s[i] == t[j])
                ans = (ans + go (i + 1, j + 1)) % mod;
    cout << ans << endl;
    return 0;
}

No comments:

Post a Comment