題目傳送門
題目大意:給出乙個序列,求 ∑1≤
i≤j≤
n(f(
i,j)
)2
\sum_(f(i,j))^2
∑1≤i≤j
≤n(
f(i,
j))2
,其中 f(i
,j
)f(i,j)
f(i,j)
表示 i
ii ~ j
jj 有多少個不同的元素。
思路挺簡單的,先考慮固定 l=1
l=1l=
1,然後求出所有 f(1
,r
)f(1,r)
f(1,r)
以及他們的平方和,將 f(1
,r
)f(1,r)
f(1,r)
們放到乙個樹狀陣列裡面。
然後將 l
ll 一位一位右移,每次右移一位,原來位置的元素就要從 f(l
,r
)f(l,r)
f(l,r)
中剔除掉,設 nex
t[ai
]next[a_i]
next[a
i] 為顏色 a
ia_i
ai 下乙個出現的位置,那麼 f(l
,p)(
p∈[l
,nex
t[ai
−1]]
)f(l,p)~(p\in[l,next[a_i-1]])
f(l,p)
(p∈[
l,ne
xt[a
i−1
]]) 都要減一,然後看答案的變化:(x−
1)2=
x2−2
x+
1(x-1)^2=x^2-2x+1
(x−1)2
=x2−
2x+1
,也就是說,答案要減去 2
×2\times
2×f (l
,p
)f(l,p)
f(l,p)
再加 nex
t[ai
]−
inext[a_i]-i
next[a
i]−
i。由於這題還有點卡常,所以不要用 map
mapma
p(不然只有 70
7070
分),離散化一下即可。
**如下:
#include
#include
using
namespace std;
#define maxn 1000010
#define mod 1000000007
#define ll long long
int n,a[maxn]
,f[maxn]
,last[maxn]
;int next[maxn]
;ll tr1[maxn]
,tr2[maxn]
;ll change
(int x,
int y)
ll sum
(int x)
ll getsum
(int x,
int y)
;struct disc
;bool
compp
(disc x,disc y)
void
discretization
(int
*darr,
int dn)
inline
charcn(
)#define cn getchar
void
read
(int
&x)while
(ch>=
'0'&&ch<=
'9')x=x*10+
(ch-
'0')
,ch=cn(
); x*
=f1;
}int
main()
ans=last_ans;
for(
int i=
1;i<=n;i++
)for
(int i=
1;i<=n;i++
)printf
("%d"
,ans)
;}
NOI Online 2 提高組 子串行問題
給定乙個長度為 n 的正整數序列 a 定義乙個函式 f l,r 表示 序列中下標在 l,r 範圍內的子區間中,不同的整數個數。現在,請你求出 sum n sum n f l,r 2 由於答案可能很大,請輸出答案對 10 9 7 取模的結果。挺有意思的題目。比如乙個數 a i 它對哪些 f 是有貢獻的...
NOI Online 2 提高組 子串行問題
題目已經說得很清楚了 我們考慮記 f i sum if k,i 2 考慮 f i 如何由 f 遞推過來 我們用 pre 表示 a i 這個值上一次出現的位置 從未出現過則記為0 下面簡記為 j 根據定義,f i sum if k,i 2 f sum f k,i 1 2 同時對於 forall k l...
NOI Online 2 提高組 遊記
沒 noi online 1 掛的慘就來寫遊記吧,不知道為啥 noi online 1 民間資料測得 60 分的 t1 最後爆零了.昏昏沉沉的醒來,吃了早飯,等到 8 30 進入比賽網頁。這次 ccf 吸取了上次的教訓,上去很快一點都不卡 體驗感很好 先看了 t1,然後突然覺得自己打某次 cf 做過...