time:2016.05.28
author:xiaoyimi
思路:
(考場上寫的60分kmp……)
學過字尾陣列的都知道,乙個串裡不同子串的個數=∑(
n−sa
[i]−
heig
ht[i
])對於問題中串每次插入乙個數字,它實際上使長度增加了1,即∑n
=n2=
(n+1
)2,對答案的貢獻是2n+1,注意這裡的n不是總長,而是插入前的串的長度,而∑s
a[i]
=n(n
−1) ,對答案的貢獻是-n,所以每次增加的就是n+1,同時插入的數字會對相鄰的height產生影響,並會產生新的兩個height,查詢排名這個東西可以用splay解決,求任意兩個子串(實際上這裡是字尾)的lcp直接預處理st表就可以了
注意:
開long long,且處理後的串是倒轉的,注意下標
**:
#include#define m 100003
#define ll long long
using namespace std;
int n,root;
int w[m],sa[m],rank[m],tmp[m],cnt[m],id[m],height[m],f[m][18];
ll ans;
struct splaya[m];
struct discb[m];
bool cmp(disc x,disc y)
void sa(int
len,int up)
}void height(int
len)
}int lcp(int a,int b)
void made(int id,int x)
void rorate(int x,bool mk)
a[x].fa=a[y].fa;
a[y].fa=x;
a[x].ch[mk]=y;
ct(y);ct(x);
}void splay(int x,int goal)
else
if (a[a[y].fa].ch[0]==y)
else
}if(!goal) root=x;
}void insert(int id,int x)
intnow=root,f=1;
while (f)
splay(id,0);
}int find_next_max(int x)
int find_next_min(int x)
main()
}
BZOJ 4516 生成魔咒
串串長度 n 1 05 n leq 10 5 n 10 5,串中元素x 1 09 x leq 10 9 x 10 9,問每加入乙個數後本質不同的子串數 裸的s am samsa m或者是離線sasa sa。這裡討論sasa sa做法。實際上問題就是把整個串翻轉一下 然後就相當於計算完每個串的貢獻以後...
bzoj4516 SDOI2016 生成魔咒
time limit 10 sec memory limit 128 mb submit 376 solved 232 submit status discuss 魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1 2 拼湊起來形成乙個魔咒串 1,2 乙個魔咒串 s 的非空字串...
bzoj4516 Sdoi2016 生成魔咒
4516 sdoi2016 生成魔咒 time limit 10 sec memory limit 128 mb submit 575 solved 327 submit status discuss 魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1 2 拼湊起來形成乙個魔咒...