NOI Online 2 提高組 子串行問題

2022-06-10 23:24:18 字數 1155 閱讀 4796

題目已經說得很清楚了

我們考慮記\(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\le j\)有\(f_==f_\)

對於\(\forall k> j\)有\(f_==f_+1\)其中\(f_\)定義為\(0\)

因此\(f_i-f_=\sum_^i((f_+1)^2-f_^2)\)

稍微推下柿子可得\(原式=(i-j)+2\sum_^f_\)

然後就可以發現這就是乙個區間加&區間求和的東西,直接上線段樹來維護就可以了

最後答案就是\(ans=\sum_^nf_i\)

#includeusing namespace std;

const int n=1e6+5,mod=1e9+7;

int n,a[n],b[n],pre[n],f[n];

inline int read()

inline int add(int x,int y)

struct sgt

inline void down(int rt,int l,int r)

void upd(int rt,int ll,int rr,int l=1,int r=n)

down(rt,l,r);

int mid=(l+r)>>1;

if(ll<=mid)upd(lc,ll,rr,l,mid);

if(mid>1,anss=0;

if(ll<=mid)anss=add(anss,query(lc,ll,rr,l,mid));

if(midup(rt);return anss;

} #undef lc

#undef rc

}t;int main()

int ans=0;

for(int i=1;i<=n;++i)ans=add(ans,f[i]);

printf("%d\n",ans);

return 0;

}

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 提高組 遊記

沒 noi online 1 掛的慘就來寫遊記吧,不知道為啥 noi online 1 民間資料測得 60 分的 t1 最後爆零了.昏昏沉沉的醒來,吃了早飯,等到 8 30 進入比賽網頁。這次 ccf 吸取了上次的教訓,上去很快一點都不卡 體驗感很好 先看了 t1,然後突然覺得自己打某次 cf 做過...

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

題目傳送門 題目大意 給出乙個序列,求 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...