給出n個字串si,m次詢問,第i次詢問sli~sri這些字串中有多少個是字串pi的母串。 ∑|
si|,
∑|pi
|<=5∗
105顯然我們需要離線回答。
把所有的pi建一棵ac自動機。
然後把詢問差分,變成字首的形式。
那麼我們只需要每次把乙個主串放在ac自動機上跑一跑,然後把經過的點和它在fail樹中到根的路徑全部+1.但是每個點只會加一次(因為沒讓你統計出現次數)
於是我們可以把這個操作用樹狀陣列維護dfs序的形式來完成。
如果我們按dfs序的順序進行修改操作,那麼x和la所重複的路徑一定是lca(x,la)到根的這段路。
那麼我們可以求出所有點然後按dfs序排序,然後操作。
也就是說我們要茲瓷修改乙個點到根的路徑,以及單點查詢。
那麼我們可以這樣做:如果乙個操作y對點x有影響,那麼y一定存在於x的子樹當中。
於是我們這個東西等價於單點修改,子樹詢問。
然後這道題就解決了。
那些讓c++選手去寫vector的出題人都應該拖出去續了
#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,a) for(int i=la[a];i;i=ne[i])
#define n 500005
using
namespace
std;
typedef
vector
vec;
struct notea[n*2];
bool cmp(note x,note y)
void insert(int x,int y)
int query(int x)
void makefail() else next[x]=1;
link(next[x],x);
d[++j]=x;}}
}void add(vec s)
}void dfs(int x)
int lca(int x,int y)
int main()
fo(i,1,m)
a[++tot].x=le-1;a[tot].bz=-1;a[tot].id=i;a[tot].p=x;
a[++tot].x=ri;a[tot].bz=1;a[tot].id=i;a[tot].p=x;
}sort(a+1,a+tot+1,cmp);makefail();tot=0;
dfs(1);int j=0;while (!a[j+1].x) j++;
fo(i,1,n)
while (a[j+1].x==i) j++,an[a[j].id]+=a[j].bz*(query(out[a[j].p])-query(in[a[j].p]-1));
}fo(i,1,m) printf("%d\n",an[i]);
}
GDOI2017模擬8 12 躲藏
給出乙個n m的網格圖,圖中有一些障礙節點。現在有a個男生和b個女生,還有乙個小標。男生要和女生配對,小標可以和任何乙個人配對。每一對cp 霧 只能待在乙個點。乙個點只能有一對cp。現在給出a b 1個人的初始座標,和他們的移動速度 即移動到4相鄰格仔所需的時間 所有人同時移動,求完成配對的最小時間...
GDOI2017模擬8 12 新車
平面上有乙個數軸,e點為目標點。你現在要開 車從w前往e,每移動1格需要1l油。你的油箱容量為s,初始時裝滿了98 汽油。數軸上有n個加油站,每個加油站提供98 95 92 中的一種。到了加油站你可以選擇加任意數量的油,你的油箱是茲瓷所有油甚至混合油的。你認為98 最吼,95 其次,92 跑的最慢。...
GDOI2017模擬11 5 總結
看到第一題,哇,數論題,不會啊,感覺要跪 正當我迷茫的時候,突然機房斷電了。啪的一聲大家的電腦都黑了!不知所措!沒辦法,只好等等。過了10分鐘左右,來電了,重新看了看第一題,也許是冷靜下來了,發現直接暴力分解質因數就能過!繼續看第二題,在草稿紙上推了一下,要用揹包,一開始以為會超時,但仔細想了想發現...