NOI Online2 提高組 子串行問題 題解

2021-10-06 14:29:02 字數 2195 閱讀 7794

題目傳送門

題目大意:給出乙個序列,求 ∑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 做過...