Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// __Macro's__
- // #pragma GCC optimize("-O0")
- #include <bits/stdc++.h>
- using namespace std;
- #define ll long long
- #define II pair<int,int>
- #define III pair<int, II>
- #define VI vector<int>
- #define VII vector<II>
- #define VIII vector<III>
- #define VVI vector<vector<int> >
- #define VVII vector<vector<II> >
- #define fr first
- #define sc second
- #define mkpr make_pair
- #define PQ priority_queue
- #define pb push_back
- #define eb emplace_back
- #define all(v) v.begin(), v.end()
- #define LINE putc('\n', stdout)
- #define SPACE putc(' ' , stdout)
- #define TAB putc('\t', stdout)
- #define fillarr(arr, val) fill((int*)arr, (int*)arr+(sizeof(arr)/sizeof(int)), val)
- #define Log2(x) (31^__builtin_clz(x))
- #define inf 1000000007
- #define MOD 1000000007
- #define getint ReadInt()
- const char IO_MODE = 3; // in-->00<--out (MSB-->LSB) | 0: Norm, 1: Fast
- inline ll ReadInt(){ll x=0,s=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';
- c=getchar();}return s*x;}inline void WriteInt(ll x){char c[20];if(!x){putchar('0');return;}if(x<0)putchar('-'),x=-x;int i=0;while(x>0)
- c[++i]=x%10,x/=10;while(i)putchar(c[i--]+48);}template <typename T>inline void out(T x){if(IO_MODE&1)WriteInt(x);else if(typeid(x)==typeid(int))
- printf("%i", x);else printf("%lld", (ll)x);}template<typename T, typename... Args>inline void out(T x,Args...args){out(x);SPACE;out(args...);}
- template <typename T>inline void in(T &x){if(IO_MODE&2) x=ReadInt();else if(typeid(x)==typeid(int))scanf("%i",&x);else if(typeid(x)==typeid(ll))
- scanf("%lld",&x);}template<typename T, typename... Args>inline void in(T &x,Args&...args){in(x);in(args...);}
- int aa,bb,cc,dd,ee,ff,gg,hh,ii,jj,kk,mm,nn,oo,pp,qq,rr,ss,tt,uu,vv,ww,xx,yy,zz;
- int tc;
- ///
- /// ---------------------------------------------- (Debug) -----------------------------------------------
- #define dbg debug()
- #define sim template < class c
- #define ris return * this
- #define dor > debug & operator <<
- #define eni(x) sim > typename enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
- sim > struct rge { c b, e; }; sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
- sim > auto dud(c* x) -> decltype(cerr << *x, 0); sim > char dud(...);
- struct debug {
- #ifdef LOCAL
- ~debug() { cerr << endl; }
- eni(!=) cerr << boolalpha << i; ris; }
- eni(==) ris << range(begin(i), end(i));}
- sim, class b dor(pair < b, c > d) {ris << "(" << d.first << ", " << d.second << ")";}
- sim dor(rge<c> d) {*this << "["; for (auto it = d.b; it != d.e; ++it) *this << ", " + 2 * (it == d.b) << *it; ris << "]";}
- #else
- sim dor(const c&) { ris; }
- #endif
- };
- #define var(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
- /// ------------------------------------------------------------------------------------------------------
- #ifdef LOCAL
- #define nax 1000
- #define qax 1000
- #else
- #define nax 400100
- #define qax 500100
- #endif
- int m;
- char S[nax];
- int A[nax];
- int Ans[qax];
- int sz[2];
- struct SuffixArray{
- int suf[nax], cnt[nax], rnk[nax], lcp[nax];
- void build(int* s, int n){
- if(n<=1) return;
- int m = max(n,256);
- Skew(s, suf, n, m);
- }
- inline bool leq(int a1, int a2, int b1, int b2){return a1<b1||a1==b1&&a2<=b2;}
- inline bool leq(int a1, int a2, int a3, int b1, int b2, int b3){return a1<b1||a1==b1&&leq(a2,a3,b2,b3);}
- void radixPass(int* a, int* b, int* c, int n, int K){
- memset(cnt, 0, ++K*sizeof(int));
- for(int i=0 ; i<n ; i++) cnt[c[a[i]]]++;
- for(int i=1 ; i<K ; i++) cnt[i]+=cnt[i-1];
- for(int i=n ; i-- ; ) b[--cnt[c[a[i]]]]=a[i];
- }
- void Skew(int* s, int* SA, int n, int K){
- int n0=(n+2)/3, n1=(n+1)/3, n2=n/3, n02=n0+n2;
- int* s12 = new int[n02+3]; s12[n02]= s12[n02+1]= s12[n02+2]=0;
- int* SA12 = new int[n02+3]; SA12[n02]=SA12[n02+1]=SA12[n02+2]=0;
- int* s0 = new int[n0];
- int* SA0 = new int[n0];
- for(int i=0,j=0 ; i<n+(n0-n1) ; i++) if(i%3) s12[j++]=i;
- radixPass(s12 , SA12, s+2, n02, K);
- radixPass(SA12, s12 , s+1, n02, K);
- radixPass(s12 , SA12, s , n02, K);
- int name=0, c0=-1, c1=-1, c2=-1;
- for(int i=0 ; i<n02 ; i++){
- if(s[SA12[i]]!=c0 || s[SA12[i]+1]!=c1 || s[SA12[i]+2]!=c2)
- name++; c0=s[SA12[i]]; c1=s[SA12[i]+1]; c2=s[SA12[i]+2];
- if(SA12[i]%3==1) s12[SA12[i]/3]=name;
- else s12[SA12[i]/3+n0]=name;
- }
- if(name<n02){
- Skew(s12, SA12, n02, name);
- for(int i=0 ; i<n02 ; i++) s12[SA12[i]]=i+1;
- }
- else for(int i=0 ; i<n02 ; i++) SA12[s12[i]-1]=i;
- for (int i=0, j=0 ; i<n02 ; i++) if(SA12[i]<n0) s0[j++]=3*SA12[i];
- radixPass(s0, SA0, s, n0, K);
- #define getIdx() (SA12[t] < n0 ? SA12[t] * 3 + 1 : (SA12[t] - n0) * 3 + 2)
- for(int p=0, t=n0-n1, k=0 ; k<n ; k++){
- int i = getIdx();
- int j = SA0[p];
- if(SA12[t]<n0? leq(s[i],s12[SA12[t]+n0], s[j],s12[j/3]) : leq(s[i],s[i+1],s12[SA12[t]-n0+1], s[j],s[j+1],s12[j/3+n0])){
- SA[k]=i; t++;
- if(t==n02) for(k++ ; p<n0 ; p++,k++) SA[k]=SA0[p];
- }
- else{
- SA[k]=j; p++;
- if(p==n0) for(k++ ; t<n02 ; t++,k++) SA[k]=getIdx();
- }
- }
- delete [] s12; delete [] SA12; delete [] SA0; delete [] s0;
- }
- void KasaiLCP(int *s, int n){
- int k=0;
- for(int i=0 ; i<n ; i++) rnk[suf[i]]=i;
- for(int i=0 ; i<n ; i++)
- if(rnk[i]==n-1) k=0;
- else{
- int j = suf[rnk[i]+1];
- while( i+k<n && j+k<n && s[i+k]==s[j+k] ) k++;
- lcp[rnk[i]]=k;
- if(k) k--;
- }
- }
- int& operator[](int i){return suf[i];}
- }Sa{};
- struct SparseTable{
- int n, *A, M[nax][Log2(nax)+1];
- void build(int *_A, int _n){ A=_A, n=_n;
- for(int i=0 ; i<n ; i++) M[i][0]=i;
- for(int j=1 ; (1<<j) <= n ; j++)
- for(int i=0 ; i+(1<<j)-1<n ; i++)
- M[i][j] = A[M[i][j-1]] <= A[M[i+(1<<j-1)][j-1]] ? M[i][j-1] : M[i+(1<<j-1)][j-1];
- }
- int inline rmnq(int l, int r){
- int k = Log2(r-l+1);
- return A[M[l][k]] <= A[M[r-(1<<k)+1][k]] ? M[l][k] : M[r-(1<<k)+1][k];
- }
- }St;
- inline int getNext(int i, int tar){
- int ans=i;
- int lo=i+1;
- int hi=sz[1]-1;
- while(lo<=hi){
- int mid = lo+hi>>1;
- if(Sa.lcp[St.rmnq(i, mid-1)]>=tar) ans=mid, lo=mid+1;
- else hi=mid-1;
- }
- return ans;
- }
- inline int getPrev(int i, int tar){
- int ans=i;
- int lo=0;
- int hi=i-1;
- while(lo<=hi){
- int mid = lo+hi>>1;
- if(Sa.lcp[St.rmnq(mid, i-1)]>=tar) ans=mid, hi=mid-1;
- else lo = mid+1;
- }
- return ans;
- }
- struct Fenwick{
- int n;
- VI fn;
- build(int sz){
- n=sz; fn.assign(n+2, 0);
- }
- void clear(){
- fn.assign(n+2, 0);
- }
- void upd(int i, int inc){
- for(;i<=n;i+=i&-i) fn[i]+=inc;
- }
- int rsq(int i){
- int sum=0;
- for(;i;i-=i&-i) sum+=fn[i];
- return sum;
- }
- int rsq(int i, int j){
- return rsq(j)-(i==1?0:rsq(i-1));
- }
- }Fn;
- int main()
- {
- scanf("%s", S);
- sz[0] = strlen(S);
- S[sz[0]++] = '$';
- scanf("%s", S+sz[0]);
- sz[1] = sz[0] + strlen(S+sz[0]);
- for(int i=0 ; i<sz[1] ; i++) A[i]=S[i];
- Sa.build(A, sz[1]);
- Sa.KasaiLCP(A, sz[1]);
- St.build(Sa.lcp, sz[1]-1);
- vector<pair<II, II>> QryL, QryR;
- in(m);
- for(int i=0 ; i<m ; i++)
- {
- int idx = getint-1;
- int len = getint-idx;
- int L = getint-1 + sz[0];
- int R = getint-1 + sz[0] - len + 1;
- if(L>R) continue;
- int SaIdx = Sa.rnk[idx];
- int SaL = getPrev(SaIdx, len);
- int SaR = getNext(SaIdx, len);
- QryL.eb(mkpr(R, i), mkpr(SaL, SaR));
- QryR.eb(mkpr(L, i), mkpr(SaL, SaR));
- }
- sort(QryL.begin(), QryL.end()); reverse(QryL.begin(), QryL.end());
- sort(QryR.begin(), QryR.end());
- Fn.build(sz[1]);
- for(int i=0 ; i<sz[1] ; i++)
- {
- Fn.upd(Sa.rnk[i]+1, +1);
- while(!QryL.empty() && QryL.back().fr.fr<=i)
- {
- int L = QryL.back().sc.fr;
- int R = QryL.back().sc.sc;
- Ans[QryL.back().fr.sc] += Fn.rsq(L+1, R+1);
- QryL.pop_back();
- }
- }
- Fn.clear();
- for(int i=sz[1]-1 ; i>=0 ; i--)
- {
- Fn.upd(Sa.rnk[i]+1, +1);
- while(!QryR.empty() && QryR.back().fr.fr>=i)
- {
- int L = QryR.back().sc.fr;
- int R = QryR.back().sc.sc;
- Ans[QryR.back().fr.sc] += Fn.rsq(L+1, R+1);
- Ans[QryR.back().fr.sc] -= R - L + 1;
- QryR.pop_back();
- }
- }
- for(int i=0 ; i<m ; i++)
- out(Ans[i]), LINE;
- }
Advertisement
Add Comment
Please, Sign In to add comment