# Codeforces878E. Numbers on the blackboard

$n \leq 100000$的数列，数字范围$-1e9,1e9$，现$q \leq 1e5$个每次问在一个区间玩游戏，能得到的最大的数。“游戏”：选相邻两个数$a_x,a_y$，然后把他们删掉，变成$a_x+2a_y$，直到序列中只剩一个数。答案$\mod \ \ 1e9+7$。

 1 //#include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 //#include<math.h>
5 //#include<set>
6 //#include<queue>
7 //#include<vector>
8 #include<algorithm>
9 #include<stdlib.h>
10 using namespace std;
11
12 #define LL long long
14 {
15     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
17 }
18
19 //Pay attention to '-' , LL and double of qread!!!!
20
21 int n,m;
22 #define maxn 100011
23 const int mod=1e9+7;
24
25 int a[maxn],pos[maxn],bin[maxn],inv[maxn],sum[maxn],lp=0,val[maxn],vv[maxn],svv[maxn];
26 struct Ques{int l,r,id; bool operator < (const Ques &b) const {return r<b.r;} }q[maxn];
27 int ans[maxn];
28
29 int WWW(LL v) {return v>2000000001?2000000001:v;}
30
31 int main()
32 {
34     bin[0]=inv[0]=1; for (int i=1;i<=n;i++)
36         sum[i]=((sum[i-1]+1ll*a[i]*bin[i])%mod+mod)%mod;
38     sort(q+1,q+1+m);
39
40     pos[lp=1]=1; int j=1; val[1]=a[1]*2; vv[1]=svv[1]=((a[1]*2)%mod+mod)%mod;
41     while (j<=m && q[j].r==1) ans[q[j].id]=(a[1]+mod)%mod,j++;
42     for (int i=2;i<=n;i++)
43     {
44         if (a[i]<=0) pos[++lp]=i,val[lp]=2*a[i],vv[lp]=(a[i]*2ll%mod+mod)%mod,svv[lp]=(svv[lp-1]+vv[lp])%mod;
45         else
46         {
47             int cur=WWW(0ll+val[lp]+bin[pos[lp]-pos[lp-1]+1]*1ll*a[i]);
48             int cvv=(vv[lp]+bin[pos[lp]-pos[lp-1]+1]*1ll*a[i])%mod; lp--;
49             while (lp && cur>0)
50             {
51                 cur=WWW(0ll+val[lp]+(pos[lp]-pos[lp-1]>31?2000000001:bin[pos[lp]-pos[lp-1]])*1ll*cur);
52                 cvv=(vv[lp]+bin[pos[lp]-pos[lp-1]]*1ll*cvv)%mod; lp--;
53             }
54             val[++lp]=cur; pos[lp]=i; vv[lp]=cvv; svv[lp]=(svv[lp-1]+vv[lp])%mod;
55         }
56         while (j<=m && q[j].r==i)
57         {
58             if (q[j].l==q[j].r) {ans[q[j].id]=(a[i]+mod)%mod; j++; continue;}
59             int l=q[j].l+1,Ans=(a[q[j].l]+mod)%mod;
60             int L=1,R=lp;
61             while (L<R)
62             {
63                 int mid=(L+R)>>1;
64                 if (pos[mid]>=l) R=mid; else L=mid+1;
65             }
66             Ans=(Ans+svv[lp]-svv[L])%mod; Ans=(Ans+mod)%mod;
67             Ans=(Ans+(sum[pos[L]]-sum[l-1]+mod)*1ll*inv[l-1])%mod;
68             ans[q[j].id]=Ans;
69             j++;
70         }
71     }
72
73     for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
74     return 0;
75 }
View Code

posted @ 2018-06-16 14:24  Blue233333  阅读(334)  评论(0编辑  收藏  举报