題目已經說得很清楚了
我們考慮記\(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...