CodeForces 315E - Sereja and Subsequences 阅读理解+树状数组

来源:互联网 发布:搜狗 mac 设置 编辑:程序博客网 时间:2024/05/21 03:56

     题目好久才看懂.....意思是在将这串所有非降子串值相加...子串值的定义是这串中所有元素相乘.

    ai最大为10^6...用一个10^6大的树状数组来维护(线段树也可以..不过空间和时间都会差一些)...从左扫到右...插入查找更新答案...

    值得注意的是元素相等的情况..如样例二 

             1 2 2  -> (1 , 2 , 12 , 22 , 122)=13   

    可见元素相同时不需要重复计算....所以每次在更新答案时..减去这个元素前上次更新的值... 


Program:

#include<iostream>#include<stdio.h>#include<string.h>#include<cmath>#include<queue>#include<stack>#include<set>#include<algorithm>#define ll long long#define oo 1000000007#define pi acos(-1.0)#define MAXN 10000005using namespace std;  ll S[MAXN],Pre[MAXN];ll getsum(int k){       ll sum=0;       while (k)       {             sum=(sum+S[k])%oo;             k-=k&(-k);       }       return sum;}void update(int k,ll x) {       while (k<=MAXN)       {             S[k]=(S[k]+x)%oo;             k+=k&(-k);       }       return;}int main(){        int i,n;       ll ans;       freopen("input.txt","r",stdin);       freopen("output.txt","w",stdout);        while (~scanf("%d",&n))       {             memset(S,0,sizeof(S));             memset(Pre,0,sizeof(Pre));             ans=0;             for (i=1;i<=n;i++)             {                    ll x,t;                    scanf("%I64d",&x);                     t=(getsum(x)*x+x)%oo;                     ans=(ans+t-Pre[x])%oo;                    update(x,t-Pre[x]);                    Pre[x]=t;             }             if (ans<0) ans+=oo;             printf("%I64d\n",ans);       }       return 0;}


原创粉丝点击