BZOJ4212 神牛的養成計畫

2022-05-03 18:33:08 字數 1390 閱讀 3311

題目大意

給定$n$個字串$s$,$m$次詢問,每次詢問給定兩個字串$s_1,s_2$,求$n$個字串中有多少個串滿足$s_1$是其字首且$s_2$是其字尾。

$n\leq 2000,m\leq 10^5 \sum |s|,\sum (|s_1|+|s_2|) \leq 2\times 10^6$

題解考慮正反建$trie$樹,原題就變為了在兩棵子樹中均出現的點有多少個。

你當然可以用主席樹加二維數點解決,其實也可以將每乙個串按照正向$trie$樹$dfs$序排序,然後再反向建可持久化$trie$,每次詢問就先找到正向$dfs$序要求的區間,接著在可持久化$trie$的兩個對應的根中沿著$s_2$的反串得出答案。

複雜度為$o(n\log n+\sum |s|+\sum (|s_1|+|s_2|)+m\log n)$。

所以其實$n$甚至可以出成$10^5$級。

#include#include#include#include#include#define ll long long

#define m 2220000

#define n 2010

using namespace std;

namespace io

void putchar(char c)

void write(int x) if(x<0) x=-x,putchar('-');

while(x) ss[++top]=x%10,x/=10;

while(top) putchar(ss[top]+'0'),--top;

} int read()

}using namespace io;

char ch[m],*s[n],s1[m],s2[m]; int n,m,p[m][26],tg[n],len[n];

int sz[m],dfn[m],node[n],tot,rt,rt[n];

int cnt,t[m][26],od[n],sum[m];

int ins(int &x,char *k,int rem)

void dfs(int x)

bool cmp(int x,int y) return res;

}int main() dfs(rt),cnt=0,sort(od+1,od+n+1,cmp);

for(int i=1;i<=n;i++) ist(rt[i],rt[i-1],s[od[i]]+len[od[i]]-1,len[od[i]]);

for(int t=read(),ans=0,len1,len2,l,r;t;t--,write(ans),putchar('\n'))

l=fd(l-1),r=fd(r),ans=qry(rt[r],rt[l],s2+len2-1,len2);

}flush();return 0;

}

bzoj4212 神牛的養成計畫

portal bzoj4212 資料範圍 n 2000,m 100000 n 個字串總長度以及詢問字串總長度均 2000000 怎麼感覺自己好像沒有學過trie一樣是因為太久沒有寫所以根本沒有往那個方向想嗎 最暴力的做法的話。想法很簡單 先確定哪些字串滿足 s 1 是字首,再看其中滿足 s 2 是字...

P2006 趙神牛的遊戲

題目描述 在 dnf 中,趙神牛有乙個締造者,他一共有 kk 點法力值,一共有 mm 個技能,每個技能耗費的法力值為 a ia i,可以造成的傷害為 b ib i,而 boss 的體力值為 nn,請你求出它放哪個技能,才可以打死 boss。當然,趙神牛技術很菜,他一局只放乙個技能,不過每個技能都可以...

bzoj1635 最高的牛

初始如果沒有限制,很顯然每一頭牛高度都是h 當只有乙個限制,讓h a 到h b 的高度都減1即可 容易發現兩個限制不會相交 否則必然矛盾 只會包含或相離,因此沒有影響,直接差分 線段樹即可 注意 1.不保證a 1 include2 using namespace std 3struct jia 10...