BZOJ4598 Sdoi2016 模式字串

2021-08-02 08:17:59 字數 1818 閱讀 7372

bzoj4598

求樹上滿足某些條件的點對,首先就可以想到點分治。

然後又與什麼字串匹配有關。km

p,ac

自動機…

… 之類的好像不太好用。。那就雜湊吧!

新增答案的時候有兩種情況:

那麼就分別維護從上到下的鏈和從下到上的鏈。不是所有鏈都存的,僅當「從該點到當前根的一段是若干個模式串的字首或者字尾」時才存。

發現當長度為

a 時,不僅m−

a可以更新答案,長度為km

−a的也可以。那這樣豈不是每次更新都是o(

n/m)

?存入答案的時候,其實長度為

x 和x+

km是等價的。取個模再存就好了。

看起來好像不是很難。。但是蒟蒻表示:好多優化啊!!qa

q 。。還是要把細節都想清白了再打。。

#include 

#include

#include

#include

#include

#include

#define n 1000005

#define mod 1000000007

#define inf 0x7fffffff

using namespace std;

typedef long long ll;

typedef unsigned long long ull;

const ull base=31;

ll read()

while(isdigit(ch))

return

x*f;

}int sum,t,n,m,cnt,rt,s1,s2;

ll ans;

int b[n<<1],p[n],nextedge[n<<1];

int sz[n],f[n],d[n];

int cnt[n],ccnt[n],st[n],sst[n];

char s[n];bool flag[n];

ull a[n],ha[n],ha[n],p[n],hash[n],hash[n],deep[n],deep[n];

void pre()

void add(int

x,int

y)void anode(int

x,int

y)void input_init()

scanf("%s",s+1);

for(int i=1;i<=m;i++) ha[i]=s[i]-'a'+1,ha[i]=s[m-i+1]-'a'+1;

for(int i=1;i<=n;i++) hash[i]=hash[i-1]+ha[(i-1)%m+1]*p[i-1],hash[i]=hash[i-1]+p[i-1]*ha[(i-1)%m+1];

}void get_root(int

x,int fa)

f[x]=max(f[x],sum-sz[x]);

rt=f[rt]>f[x]?x:rt;

}void get_deep(int

x,int fa)

}void calc(int

x) for(int j=1;j<=s2;j++)

for(int j=1;j<=s1;j++)

for(int j=1;j<=s2;j++)

}}void work(intx)}

int main()

return

0;}

Bzoj 2726 SDOI 任務安排

memory limit 131072kb 64bit io format lld llu description 機器上有n個需要處理的任務,它們構成了乙個序列。這些任務被標號為1到n,因此序列的排列為1,2,3.n。這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工...

BZOJ 3991 SDOI2015 尋寶遊戲

題目大意 給定一棵樹,其中有若干個關鍵點,任意選擇起點,求從起點出發訪問所有關鍵點又回到起點的最小邊權總和,有m個修改操作,每次修改乙個關鍵點。假如沒有修改操作的話,就像乙個簡單的樹形dp,方程如下 f i sigma sigma.觀察一下dp的過程,就是不斷地從前面的點走到後面的點,所以我們可以不...

SDOI2013 BZOJ3203 保護出題人

description input 第一行兩個空格隔開的正整數n和d,分別表示關數和相鄰殭屍間的距離。接下來n行每行兩個空格隔開的正整數,第i 1行為ai和 xi,分別表示相比上一關在殭屍佇列排頭增加血量為ai 點的殭屍,排頭殭屍從距離房子xi公尺處開始接近。output 乙個數,n關植物攻擊力的最...