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關植物攻擊力的最...