P6477 [NOI Online #2 提高组] 子序列问题

13 篇文章 0 订阅

参考链接:NOI Online2 提高组 子序列问题

在这里插入图片描述

  • 在做hdu第7场的1012题时想到的类似题目,用线段树去解决区间平方和问题,但是那题我还没调好我的代码。

accode:

#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){for(int i=x;i<=n;i+=(i&-i))tr1[i]=(tr1[i]+y)%mod,tr2[i]=(tr2[i]+y*(x-1)+mod)%mod;}
ll sum(int x){ll re=0;for(int i=x;i>=1;i-=(i&-i))re=(re+tr1[i]*x%mod-tr2[i]+mod)%mod;return re;}
ll getsum(int x,int y){return (sum(y)-sum(x-1)+mod)%mod;};
struct disc{int x,y;};
bool compp(disc x,disc y){return x.x<y.x;}
void discretization(int *darr,int dn) {
    static disc b[maxn];
    for(int i=1;i<=dn;i++)
    b[i].x=darr[i],b[i].y=i;
    sort(b+1,b+dn+1,compp);
    static int tot=0;b[0].x=-9666;
    for(int i=1;i<=dn;i++)
    if(b[i].x!=b[i-1].x)darr[b[i].y]=++tot;
    else darr[b[i].y]=tot;
}
inline char cn() {
    static char buf[1000010],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
#define cn getchar
void read(int &x) {
    x=0;int f1=1;char ch=cn();
    while(ch<'0'||ch>'9'){if(ch=='-')f1=-1;ch=cn();}
    while(ch>='0'&&ch<='9')x=x*10+(ch-'0'),ch=cn(); x*=f1;
}
int main() {
    read(n);
    ll last_ans=0,ans=0;
    for(int i=1;i<=n;i++)read(a[i]);
    discretization(a,n);
    for(int i=1;i<=n;i++) {
        f[i]=f[i-1];
        if(!last[a[i]])f[i]++;
        else Next[last[a[i]]]=i;
        last[a[i]]=i;
        last_ans=(last_ans+1ll*f[i]*f[i]%mod)%mod;
    }
    ans=last_ans;
    for(int i=1;i<=n;i++) {
        if(!Next[i])Next[i]=n+1;
        change(i,f[i]-f[i-1]);
    }
    for(int i=1;i<=n;i++) {
        last_ans=(1ll*last_ans-((2*getsum(i,Next[i]-1)%mod-Next[i]+mod)+i)%mod+mod)%mod;
        ans=(ans+last_ans)%mod;
        change(i,-1);change(Next[i],1);
    }
    printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值