GDOI2017模擬9 10 子串

2021-07-22 15:03:54 字數 1577 閱讀 3111

給出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分鐘左右,來電了,重新看了看第一題,也許是冷靜下來了,發現直接暴力分解質因數就能過!繼續看第二題,在草稿紙上推了一下,要用揹包,一開始以為會超時,但仔細想了想發現...