zoukankan      html  css  js  c++  java
  • [HNOI2017]影魔

    题解:

    这个题可以采取离线处理的方式.先处理出每个点i左边第一个比它大的点L[i],和右边第一个比它大的点R[i].
    那么对于区间L[i]到R[i]有p1的贡献.①
    对于左端点在L[i]+1到i-1,右端点为R[i]的区间有p2的贡献.②
    对于左端点为L[i],右端点为i+1到R[i]-1的区间也有p2的贡献.③
    所以我们离线排序处理好.
    对于①情况,我们在扫到R[i]时,更新点L[i]的贡献
    对于②情况,我们在扫到R[i]时,更新区间L[i]+1到i-1的贡献
    对于③情况,我们在扫到L[i]时,更新区间i+1到R[i]-1的贡献
    我们对于每个询问[l,r],在扫到l-1时,我们记录此时区间l到r的每个点的贡献和为sum1,然后当我们扫到r的时候,再次记录此时的区间l到r的每个点的贡献和为sum2,显然答案就是sum2-sum1了.

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstring>
     7 #include<queue>
     8 #include<vector>
     9 #include<set>
    10 #define RG register
    11 #define LL long long int
    12 #define MAXN 500010
    13 using namespace std;
    14 const int INF=1e9;
    15 struct node{
    16   int l,r,x,id,v;
    17   node(){}
    18   node(int l_,int r_,int x_,int id_,int v_):l(l_),r(r_),x(x_),id(id_),v(v_){}
    19   bool operator <(const node &tmp)const{
    20     return x<tmp.x;
    21   }
    22 }s1[MAXN],s2[MAXN];
    23 int n,m,p1,p2;
    24 int k[MAXN],q[MAXN],top;
    25 int L[MAXN],R[MAXN];
    26 LL ans[MAXN],c1[MAXN],c2[MAXN];
    27 int lowbit(int x)
    28 {
    29   return x&(-x);
    30 }
    31 void add(int x,int y)//区间修改操作
    32 {
    33   if(x) for(int i=x;i<=n;i+=lowbit(i)) c1[i]+=y,c2[i]+=(LL)x*y;
    34 }
    35 LL sum(int x)
    36 {
    37   LL num=0;
    38   for(int i=x;i>0;i-=lowbit(i)) num+=(x+1)*c1[i]-c2[i];
    39   return num;
    40 }
    41 int main()
    42 {
    43   freopen("1.in","r",stdin);
    44   scanf("%d%d%d%d",&n,&m,&p1,&p2);
    45   k[0]=k[n+1]=n+1;q[++top]=0;
    46   for(int i=1;i<=n;i++) scanf("%d",&k[i]);
    47   for(int i=1;i<=n+1;i++)
    48     {
    49       while(k[q[top]]<k[i]) R[q[top]]=i,top--;
    50       L[i]=q[top];q[++top]=i;
    51     }
    52   int x,y;
    53   for(int i=1;i<=m;i++)
    54     {
    55       scanf("%d%d",&x,&y);ans[i]+=(y-x)*p1;
    56       s1[i]=node(x,y,x-1,i,-1);s1[i+m]=node(x,y,y,i,1);
    57     }
    58   sort(s1+1,s1+2*m+1);int tot=0;
    59   for(int i=1;i<=n;i++)
    60     {
    61       if(1<=L[i]&&R[i]<=n) s2[++tot]=node(L[i],L[i],R[i],0,p1);
    62       if(1<=L[i]&&R[i]>i+1) s2[++tot]=node(i+1,R[i]-1,L[i],0,p2);
    63       if(L[i]+1<i&&R[i]<=n) s2[++tot]=node(L[i]+1,i-1,R[i],0,p2);
    64     }
    65   sort(s2+1,s2+tot+1);int n1=1,n2=1;
    66   while(!s1[n1].x) n1++;
    67   for(int i=1;n1<=m*2&&i<=n;i++)
    68     {
    69       while(n2<=tot&&s2[n2].x==i){
    70     add(s2[n2].r+1,-s2[n2].v);
    71     add(s2[n2].l,s2[n2].v);
    72     n2++;
    73       }
    74       while(n1<=m*2&&s1[n1].x==i){
    75     ans[s1[n1].id]+=s1[n1].v*(sum(s1[n1].r)-sum(s1[n1].l-1));
    76     n1++;
    77       } 
    78     }
    79   for(int i=1;i<=m;i++) printf("%lld
    ",ans[i]);
    80   return 0;
    81 }
  • 相关阅读:
    [BJWC2018]Border 的四种求法
    [51nod1847]奇怪的数学题
    [51nod1965]奇怪的式子
    [BZOJ3283]运算器
    [TJOI2015]概率论
    [SDOI2017]遗忘的集合
    [HDU5709]Claris Loves Painting
    [Atcoder AGC032C]Three Circuits
    [Atcoder ARC103D]Robot Arms
    [Atcoder AGC030C]Coloring Torus
  • 原文地址:https://www.cnblogs.com/Landlord-greatly/p/8081743.html
Copyright © 2011-2022 走看看