日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P6477-[NOI Online #2 提高组]子序列问题【线段树】

發(fā)布時(shí)間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P6477-[NOI Online #2 提高组]子序列问题【线段树】 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P6477
話說這是luogu的冥間數(shù)據(jù)


題目大意

nnn個(gè)數(shù)的序列,f(l,r)f(l,r)f(l,r)表示l~rl\sim rlr有多少個(gè)不同的數(shù)字。

∑l=1n∑r=ln(f(l,r))2\sum_{l=1}^n\sum_{r=l}^n(f(l,r))^2l=1n?r=ln?(f(l,r))2


解題思路

考慮多一個(gè)數(shù)字會(huì)多出2n+12n+12n+1(n表示原來數(shù)字個(gè)數(shù))。

線段樹維護(hù)f(1~i?1,i)f(1\sim i-1,i)f(1i?1,i)的和,然后每個(gè)數(shù)字能影響的范圍是i到上一個(gè)和它相同的數(shù)字的后一個(gè)位置處,我們修改這部分的數(shù)據(jù)然后每次統(tǒng)計(jì)答案即可。


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #define lowbit(x) (x&-x) #define siz(x) (t[x].r-t[x].l+1) #define k(x) (((x)>XJQ)?((x)-XJQ):(x)) #define ll long long using namespace std; const ll N=1e6+10,XJQ=1e9+7; ll n,ans,answer; ll a[N],b[N],last[N],v[N]; ll read() {ll x=0,f=1; char c=getchar();while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();return x*f; } struct Seq_Tree{struct Tree_node{ll l,r,val,lazy;}t[N*4];void Build(ll x,ll l,ll r){t[x].l=l;t[x].r=r;if(l==r)return;ll mid=(l+r)>>1;Build(x*2,l,mid);Build(x*2+1,mid+1,r);return;}void DownData(ll x){if(!t[x].lazy)return;(t[x*2].lazy+=t[x].lazy)%=XJQ;(t[x*2+1].lazy+=t[x].lazy)%=XJQ;(t[x*2].val+=t[x].lazy*siz(x*2))%=XJQ;(t[x*2+1].val+=t[x].lazy*siz(x*2+1))%=XJQ;t[x].lazy=0;return;}void Change(ll x,ll l,ll r,ll val){if(t[x].l==l&&t[x].r==r){(t[x].lazy+=val)%=XJQ;(t[x].val+=val*siz(x))%=XJQ;return;}DownData(x);ll mid=(t[x].l+t[x].r)>>1;if(r<=mid) Change(x*2,l,r,val);else if(l>mid) Change(x*2+1,l,r,val);else Change(x*2,l,mid,val),Change(x*2+1,mid+1,r,val);t[x].val=(t[x*2].val+t[x*2+1].val)%XJQ;return;}ll Ask(ll x,ll l,ll r){if(t[x].l==l&&t[x].r==r)return t[x].val;DownData(x);ll mid=(t[x].l+t[x].r)>>1;if(r<=mid) return Ask(x*2,l,r);if(l>mid) return Ask(x*2+1,l,r);return (Ask(x*2,l,mid)+Ask(x*2+1,mid+1,r))%XJQ;} }T; int main() {n=read();for(ll i=1;i<=n;i++)a[i]=b[i]=read();sort(b+1,b+1+n);ll m=unique(b+1,b+1+n)-b-1;for(ll i=1;i<=n;i++){a[i]=lower_bound(b+1,b+1+m,a[i])-b;last[i]=v[a[i]];v[a[i]]=i;}T.Build(1,1,n);T.Change(1,1,1,1);ans=answer=1;for(ll i=2;i<=n;i++){(ans+=2*T.Ask(1,last[i]+1,i)+i-last[i])%=XJQ;T.Change(1,last[i]+1,i,1);(answer+=ans)%=XJQ;}printf("%lld",answer); }

總結(jié)

以上是生活随笔為你收集整理的P6477-[NOI Online #2 提高组]子序列问题【线段树】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。