1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include<vector> #include<cstdio> #include<cstring> #include<algorithm> using namespace std;
const int N=1e6,MOD=1e9+7;
inline int Add(const int &a,const int &b){return a+b>=MOD? a+b-MOD:a+b;} inline int Sub(const int &a,const int &b){return a-b<0? a-b+MOD:a-b;} inline int Mul(const int &a,const int &b){return 1ll*a*b%MOD;} int QPow(int a,int b){ int ret=0; while(b){ if(b&1) ret=Mul(ret,a); a=Mul(a,a);b>>=1; } return ret; }
int n; int num[N+3],las[N+3]; vector<int> uni;
struct SEGTREE{ int sqsum[N*2+3],sum[N*2+3],add[N*2+3]; inline int Index(int lef,int rig){return (lef+rig)|(lef!=rig);} void PushUp(int lef,int rig){ int mid=(lef+rig)>>1; sum[Index(lef,rig)]=Add(sum[Index(lef,mid)],sum[Index(mid+1,rig)]); sqsum[Index(lef,rig)]=Add(sqsum[Index(lef,mid)],sqsum[Index(mid+1,rig)]); } void Update(int lef,int rig,int del){ int u=Index(lef,rig),len=rig-lef+1; sqsum[u]=Add(sqsum[u],Mul(Mul(2,del),sum[u])); sqsum[u]=Add(sqsum[u],Mul(Mul(del,del),len)); add[u]=Add(add[u],del); sum[u]=Add(sum[u],Mul(len,del)); } void PushDown(int lef,int rig){ int mid=(lef+rig)>>1,u=Index(lef,rig); if(!add[u]) return; Update(lef,mid,add[u]); Update(mid+1,rig,add[u]); add[u]=0; } void Modify(int lef,int rig,int Le,int Ri){ if(Le<=lef && rig<=Ri){ Update(lef,rig,1); return; } PushDown(lef,rig); int mid=(lef+rig)>>1; if(Le<=mid) Modify(lef,mid,Le,Ri); if(Ri>mid) Modify(mid+1,rig,Le,Ri); PushUp(lef,rig); } int SumUp(int lef,int rig,int Le,int Ri){ if(Le<=lef && rig<=Ri) return sqsum[Index(lef,rig)]; PushDown(lef,rig); int mid=(lef+rig)>>1,ret=0; if(Le<=mid) ret=Add(ret,SumUp(lef,mid,Le,Ri)); if(Ri>mid) ret=Add(ret,SumUp(mid+1,rig,Le,Ri)); return ret; } }Se;
int RI(){ int a=0,c=getchar(); while(c<'0' || '9'<c) c=getchar(); while('0'<=c && c<='9'){ a=(a<<1)+(a<<3)+c-'0'; c=getchar(); } return a; } int main(){ freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); n=RI(); for(int i=1;i<=n;i++) uni.push_back(num[i]=RI()); sort(uni.begin(),uni.end()); uni.erase(unique(uni.begin(),uni.end()),uni.end()); for(int i=1;i<=n;i++) num[i]=lower_bound(uni.begin(),uni.end(),num[i])-uni.begin()+1; for(int i=1;i<=(int)uni.size();i++) las[i]=n+1; int ans=0; for(int i=n;i>=1;i--){ int lef=i,rig=las[num[i]]-1; las[num[i]]=i; Se.Modify(1,n,lef,rig); int res=Se.SumUp(1,n,i,n); ans=Add(ans,res); } printf("%d\n",ans); return 0; }
|