bzoj 4540: [Hnoi2016]序列

额,呵呵呵一脸懵逼

贴个题解吧:http://blog.csdn.net/thy_asdf/article/details/51203510

感觉做这样的题还是多想想莫队怎么搞,毕竟不强制在线。。

 1 #include <bits/stdc++.h>
 2 #define LL long long
 3 using namespace std;
 4 inline int ra()
 5 {
 6     int x=0,f=1; char ch=getchar();
 7     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 8     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
 9     return x*f;
10 }
11 
12 const int maxn=100005;
13 
14 int n,T,block,top,a[maxn],st[maxn][20],pw[20],stk[maxn],L[maxn],R[maxn],belong[maxn],lg[maxn];
15 LL sl[maxn],sr[maxn],now,ans[maxn];  
16 struct node{int l,r,id;}q[maxn];  
17 
18 int MIN(int x, int y) {return a[x]<a[y]?x:y;}
19 void ST()
20 {
21     lg[0]=-1; pw[0]=1;
22     for (int i=1; i<=18; i++) pw[i]=pw[i-1]<<1;
23     for (int i=1; i<=n; i++) lg[i]=lg[i>>1]+1,belong[i]=(i-1)/block+1;
24     for (int i=1; i<=n; i++) st[i][0]=i;
25     for (int j=1; j<=18; j++)
26         for (int i=1; i<=n; i++)
27         {
28             st[i][j]=st[i][j-1];
29             if (i+pw[j-1]<=n) st[i][j]=MIN(st[i][j-1],st[i+pw[j-1]][j-1]);
30         }
31 }
32 
33 int cal(int l, int r)
34 {
35     if (l>r) swap(l,r);
36     int orz=lg[r-l+1];
37     return MIN(st[l][orz],st[r-pw[orz]+1][orz]);
38 }
39 void change_L(int l, int r, int opt)
40 {
41     int p=cal(l,r);
42     LL tmp=(LL)a[p]*(r-p+1)+sr[l]-sr[p];
43     now+=opt*tmp;
44 }
45 void change_R(int l, int r, int opt)
46 {
47     int p=cal(l,r);
48     LL tmp=(LL)a[p]*(p-l+1)+sl[r]-sl[p];
49     now+=opt*tmp;
50 }
51 bool cmp(node a, node b) {return belong[a.l]<belong[b.l] || (belong[a.l]==belong[b.l] && a.r<b.r);}
52 void solve()
53 {
54     sort(q+1,q+T+1,cmp); now=a[1];
55     for (int l=1,r=1,i=1; i<=T; i++)
56     {
57         while (r<q[i].r) change_R(l,++r,1);
58         while (l>q[i].l) change_L(--l,r,1);
59         while (r>q[i].r) change_R(l,r--,-1);
60         while (l<q[i].l) change_L(l++,r,-1);
61         ans[q[i].id]=now; 
62     }
63     for (int i=1; i<=T; i++) printf("%lld\n",ans[i]);
64 }
65 int main(int argc, char const *argv[])
66 {
67     n=ra(); T=ra(); block=sqrt(n); 
68     for (int i=1; i<=n; i++) a[i]=ra();
69     ST();
70     for (int i=1; i<=n; i++)
71     {
72         while (top && a[stk[top]]>=a[i]) R[stk[top--]]=i;
73         stk[++top]=i;
74     }
75     while (top) R[stk[top--]]=n+1;
76     for (int i=n; i>=1; i--)
77     {
78         while (top && a[stk[top]]>a[i]) L[stk[top--]]=i;
79         stk[++top]=i;
80     }
81     while (top) L[stk[top--]]=0;
82     for (int i=n; i>=1; i--) sr[i]=sr[R[i]]+(LL)(R[i]-i)*a[i];
83     for (int i=1; i<=n; i++) sl[i]=sl[L[i]]+(LL)(i-L[i])*a[i];
84     for (int i=1; i<=T; i++) q[i].l=ra(),q[i].r=ra(),q[i].id=i;
85     solve(); 
86     return 0;
87 }

 

posted @ 2017-05-02 10:11  ws_ccd  阅读(190)  评论(0编辑  收藏  举报