zm bun

[Background] Topic:
zm liked the bun.
[Title] face Description:
zm every day to buy buns, but in order to lose weight, zm set a series of rules to control the number of buns he bought every day.
He randomly a special string of n, then n string to measure the number of days in the next Q buy buns every day.
Rules are as follows:
1. zm generates two strings day, he called string A string, another string called B string.
2. At this time, each string has a special value F [i], where A is the i-th string special string prefix and suffix B sequence when the i-th string (may overlap), F [i] = 1 otherwise, F [i] = 0.
3. If F [i] is currently equal to 1, then that zm buy the bun. zm every night would do a dream, the dream will be a digital K, zm think this figure unlucky, they wanted him to buy a small number of K buns to zackzh, then I zm wanted to know the number of buns. zm think this problem is too simple for him, then found you, let you on his behalf to write a program to solve this problem.
[Input format:
Enter the file zmchibaozi.in.
The first line contains two numbers n, Q. Next n lines, each line represents a particular string. Next Q rows, each row represents the day A string generated zm, B strings and K.
[Output format]:
Output to a file zmchibaozi.out. Q co rows, each row represents the day numbering K zm buy small buns, -1 is output if no solutions.
[Sample input]:
3 6
aaaaa
Spearheading
bus
a a 1
a aa 2
aa a 2
aaaaa aaaa 1
ABAC Horse 3
ABAC 1
[] Sample output:
1
2
-1
1
-1
2
【data range】:
Represents the total length of a special string s1, s2 denotes the total length of string A, s3 represents the total length of the B string.
For 10% of the data, s1, s2, s3 <= 5000.
There are additional 10% of the data, like all the A string.
There are additional 10% of the data, like all the B string.
There are an additional 30% of the data, each of the A string and B string length is less than 20 and n <= 10000.
To 100% of the data, s1 <= 1000000, s2, s3 <= 2000000, K <= n, m <= 100000, all lowercase string.
[Resolved] title
First of all the special strings can be found on the node position A, B string on these two trie built by two trie tree when positive and negative, so that after each inquiry, the answer is both child nodes of the tree are common K large number of nodes nodes.
Abstract model can continue.
It is between a node in this subtree root of its dfn dfn and dfn + siz-1.
You can get such a problem
FIG x represents a positive trie dfn, y represents the trie anti dfn.
Each string into a specific point (the trie forward dfn, reverse the trie dfn).
Each inquiry will first convert two large K subtrees CCP is a little big point of seeking rectangle K.
It will be transformed into the classic problem of the whole half.
Scanning lines to solve.
code show as below:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,q,size,ans[N],ge,cnt1,cnt2,sh[N],dq[N],dui[N],cj,cc[N];
struct ztef
{
    int x1,x2,y1,y2,k,id;
}a[N<<1],huan2[N];
struct cha
{
    int qi,ho;
}b[N],huan[N];
struct line
{
    int he,ze1,ze2,pu,du;
}li[N<<1];
string s,ss;
struct pigu
{
    int er[N][27],dfn[N],cnt,siz[N];
    inline int insert(string x)
    {
        int len=x.size(),now=0;
        for(int i=0;i<len;i++)
        {
            if(!er[now][x[i]-'a']) er[now][x[i]-'a']=++cnt;
            now=er[now][x[i]-'a'];
        }
        return now;
    }
    inline void dfs(int now)
    {
        dfn[now]=++size;siz[now]=1;
        for(int i=0;i<=25;i++)
        {
            if(!er[now][i]) continue;
            dfs(er[now][i]);
            siz[now]+=siz[er[now][i]];
        }
    }
    inline int cha(string x)
    {
        int now=0,len=x.size();
        for(int i=0;i<len;i++)
        {
            if(!er[now][x[i]-'a']) return 0;
             now=er[now][x[i]-'a'];
        }
        return now;
    }
}zh,fa;
inline int read()
{
    char c=getchar();
    int x=0,f=1;
    while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
    while(isdigit(c)) {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return x*f;
}
inline int lowbit(int x)
{
    return x&(-x);
}
inline void update(int now,int v)
{
    while(now<=cj)
    {
        sh[now]+=v;
        now+=lowbit(now);
    }
}
inline int query(int now)
{
    int daan=0;
    if(now<=0) return 0;
    while(now)
    {
        daan+=sh[now];
        now-=lowbit(now);
    }
    return daan;
}
inline bool cmp2(line x,line y)
{
    return x.he<y.he;
}
inline bool cmp1(cha x,cha y)
{
    return x.qi<y.qi;
}
inline void solve(int l,int r,int L,int R)
{
    if(L>R) return;
    if(l==r)
    {
        if(r==n+1) for(int i=L;i<=R;i++) ans[dui[i]]=-1;
        else for(int i=L;i<=R;i++) ans[dui[i]]=l;
        return;
    }
    int cn3=1,mid=(l+r)>>1,cn1=0,cn2=0;
    for(int i=l;i<=mid;i++)
        [Huan ++ CN1] = B [I]; 
    Sort (Huan + . 1 , Huan + CN1 + . 1 , CMP1);
     for ( int I = L; I <= R & lt; I ++ ) 
    { 
        IF (ANS [DUI [I]] == - . 1 ) Continue ; 
        Li [ ++ CN2] = (Line) {A [DUI [I]] X1-. . 1 , A [DUI [I]] Y1, A [DUI [I]] Y2,.. - . 1 , I}; 
        Li [ ++ CN2] = (Line) {A [DUI [I]] X2, A [DUI [I]] Y1, A [DUI [I]] Y2,... . 1 , I }; 
    } 
    Sort (Li + . 1 , Li + CN2 + . 1 , CMP2);
     for ( int i=1;i<=cn2;i++)
    {
        while(cn3<=cn1&&huan[cn3].qi<=li[i].he)
        {
            update(huan[cn3].ho,1);
            cn3++;
        }
        dq[li[i].du]+=(query(li[i].ze2)-query(li[i].ze1-1))*li[i].pu;
    }
    for(int i=1;i<cn3;i++)
        update(huan[i].ho,-1);
    int hu1=L,hu2=R;
    for(int i=L;i<=R;i++)
    {
        if(dq[i]>=a[dui[i]].k)
            cc[hu1++]=dui[i];
        else
        {
            cc[hu2--]=dui[i];
            a[dui[i]].k-=dq[i];
        }
        dq[i]=0;
    }
    for(int i=L;i<=R;i++) dui[i]=cc[i];
    solve(l,mid,L,hu1-1);
    solve(mid+1,r,hu2+1,R);
}
int main()
{
    n=read();q=read();
    for(int i=1;i<=n;i++)
    {
        cin>>s;
        b[i].qi=zh.insert(s);
        reverse(s.begin(),s.end());
        b[i].ho=fa.insert(s);
    }
    zh.dfs(0);size=0;fa.dfs(0);
    for(int i=1;i<=n;i++)
    {
        b[i].qi=zh.dfn[b[i].qi];
        b[i].ho=fa.dfn[b[i].ho];
    }
    cj=fa.cnt+1;
    for(int i=1,x,y,z;i<=q;i++)
    {
        cin>>s>>ss>>z;
        dui[i]=i;
        reverse(ss.begin(),ss.end());
        x=zh.cha(s);
        y=fa.cha(ss);a[i].k=z;
        if(x==0||y==0) {ans[i]=-1;continue;}
        a[i].id=i;
        a[i].x1=zh.dfn[x];a[i].x2=zh.dfn[x]+zh.siz[x]-1;
        a[i].y1=fa.dfn[y];a[i].y2=fa.dfn[y]+fa.siz[y]-1;
    } 
    solve(1,n+1,1,q);
    for(int i=1;i<=q;i++) cout<<ans[i]<<"\n";
    return 0;
} 

 

Guess you like

Origin www.cnblogs.com/betablewaloot/p/12130294.html
Bun
Recommended