6374. [2019년 10월 4일] 워드 NOIP2019 아날로그 [삶과 죽음의 영역]

이름

효과에 따라

당신에게 열 번호를 제공하기 위해, 각각 두 인접한 번호를 선택할 수 있습니다 \ (X \)\ (Y \) , 원래의 위치에서의 삭제 및 삽입 \ (X + 2Y \) .
때마다 쿼리 간격, 위 작업의 간격. 마지막 남은 개수가 가장 많은입니다 찾을 수 있습니다.
대답은 모듈이 필요합니다.


역사에 대한 고찰

이 문제를 참조하십시오, 첫 번째 생각은 다음과 같습니다가 필요하다이 질문은 최대를 제시뿐만 아니라 모듈로, 그래서 욕심해야 할 수 있습니다.
그러나, ......
\ (O (3 ^ N-) \) 폭력 간격 직접 싸우고 수 \ (DP \) . 하지만 재생되지 않았다.
사실, 가장 큰 병목 내가, 그것은 ...... 날려 버리겠다하지만 숫자가 너무 큰 크기보다 더 필요하다는 것입니다
이 문제 자체가 비우호적 인 폭력의 문제에 직면 ......


정답

내가 재미있는 특성에 게임을 발견했을 때 사실 :
우리는 전체 범위는 두 개의 섹션으로 나누어 한, 계수 뒤의 부분은, 두 곱한 후 양측이 재귀 프로세스를 계속 운영하고 있습니다.
가정 쉽게 찾을 (\ 2 ...... {k_i} \을 ) 제 위해 (I는 \) \ 항의 계수는 \. (1 \ 당량 K_i \ 당량 K_ {I}. +1 1- \) \ (= 0 k_1 \)
여러 가지로 응답 시퀀스 일 수있다 ) k_i \ (\ 연산의 각 시리즈의 시작 부분에서 연산의 순서가된다 (1 \)를 \ 제외한 이전 (제 1 연산 시퀀스의 끝).

그러나, 더 마법의 결론은있다 : \ (K_i \)\ (1 \) , 또는 \ (K_ {I-1}
1 \) 단순히 그것을 증명 :
산술 순서를 들어, 그것이 무엇인지 기억 와. 이상과 같음하는 경우 (0 \)를 \ 다음 나중에 더 좋을 것이다 선행 연산 시퀀스들 중 하나에 접속되고; 미만인 \ (0 \) 상기의 그 시작 \ (K \) 로 설정된다 (\ 1 \) 가장 우수한.

모든 문의를 고려하지 마십시오. 쿼리 가정 (1 \)는 \ 시작, 증분 방식은 연산 시퀀스를 구성한다.
먼저, 노드를 추가, \ (K_i \)는 하기 (1 \) \ , 다음, 전면과 병합하려고합니다.
보다 크거나 같은 경우 \ (0 \) , 앞쪽으로 이동한다. 픽 업 후 합병 앞을 계속하려고합니다.
또는 전면으로 이동하지 않습니다.
분명히 이것은 문제가되지 않습니다.

다음 질문 섹션을 처리하는 방법을 고려한다. 첫째 떨어져 오른쪽 지점 범위 주문에 따라 오른쪽 자리에 걸 부탁드립니다.
통계적 대답 포인트 연산 시퀀스를 찾기 위해 떠날 때. 때 당신이 반 또는 분리 된 세트를 찾을 수 있습니다.
수의 그 산술 시퀀스의 산술 직접가 추가 시리즈 포인트 뒤에 왼쪽. 접두사 및 구현을 사용할 수 있습니다.
왼쪽 소수점 산술 서열은 두 부분, 즉 배후 등에 직접 계산들로 분할 수있다. 시간의 계산이 가능 미리 스타트 \ (sum_i = \ sum_. 1 {J} = {I} ^ 2 ^ ja_j의 \) 뒤에 \ (SUM \) 감산 \ (L-sum_한다. 1} {\) , 에 의해 분할 \ (2 ^ L에 \) .

왜 분할 연산 순서 후에 변경되지 않습니다?
사실 만 합병 백업하지 않습니다 것을 증명해야하고,이 라인에 분할을 계속하지 않을 것이다.
돌아 가기 확실히 부정적인 때문에 앞이 변경되었습니다 그리고 그들은 최대 병합하지 않습니다.
분할하는 경우 (로 분할 가정 \ (B의 \)\ (C를 \) 의 왼쪽 분할 \ (A \) ), 일본어 및 대 \ (A + 2 ^의 xB + 2 ^ {X + Y C} \) 와 분할 된 후 \ (B ^ 2 + yC 명명 \) . 이 분할되어 있으면된다 \ (B + C \) ..
각 승산 \ (X ^ 2 \) 플러스 \ (A \) , 각각 그해진다 (A + 2 ^의 xB + \ 2 ^ {X + Y} C \) 와 \ (A + 2 ^의 xB를 ^ 2 + XC \)
전 때문에, 최적화되어야되도록 \ (2 ^ yC 명명 \ GEQ C \) 이므로 \ (C> 0 \) .
그래서 더 나은 분할하지 않습니다.

구현 될 때, 폭발하기 쉽다 long long. 양수가 큰 반면 실제로,하지만, 가장 작은 음수가 너무 작되지이다. 최소 때문에, 산술 시퀀스 (여러 숫자의 합병은 그 몇 가지 숫자의 뒷면과 약간의 음이 아닌, 다음, 그리고 훨씬 작은 뒤에 온이있는 경우) 하나의 부정적인해야합니다. 그래서 최소가 \ (- 2E9 \) .
수보다 큰 경우 \ (2E9 \) , 그 후는 부정적가되지 않습니다. 표시 \ (2E9 + 1 \) 라인에.
잘못된 기록 및 크기 비 사용 (규범)에 대한 응답을 계산하기 위해 사용되는 사실과 기록을 달성하는 시간.


코드

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500010
#define ll long long
#define INF 2000000000
#define mo 1000000007
inline ll my_pow(ll x,int y){
    ll res=1;
    for (;y;x=x*x%mo,y>>=1)
        if (y&1)
            res=res*x%mo;
    return res;
}
int n,m;
int a[N];
struct Query{
    int l,r,num;
} q[N];
inline bool cmpq(Query a,Query b){return a.r<b.r;}
ll ans[N];
ll _2,pow2[N],ipow2[N],bpow2[N],g[N];
int st[N],top;
ll sum[N],rs[N],pre[N];
int main(){
    freopen("border.in","r",stdin);
    freopen("border.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    _2=my_pow(2,mo-2);
    pow2[0]=bpow2[0]=ipow2[0]=1;
    for (int i=1;i<=n;++i){
        pow2[i]=pow2[i-1]*2%mo;
        bpow2[i]=bpow2[i-1]*2;
        bpow2[i]=(bpow2[i]>INF?INF+1:bpow2[i]);
        ipow2[i]=ipow2[i-1]*_2%mo;
        g[i]=(g[i-1]+pow2[i]*a[i])%mo;
    }
    for (int i=1;i<=m;++i)
        scanf("%d%d",&q[i].l,&q[i].r),q[i].num=i;
    sort(q+1,q+m+1,cmpq);
    st[top=1]=1,pre[1]=sum[1]=rs[1]=a[1];
    int j=1;
    for (;q[j].r<=1;++j)
        ans[q[j].num]=(a[1]+mo)%mo;
    for (int i=2;i<=n;++i){
        st[++top]=i;
        sum[top]=2*a[i];
        rs[top]=2ll*(a[i]+mo)%mo;
        while (top>1 && sum[top]>=0){
            rs[top-1]=(rs[top-1]+rs[top]*pow2[st[top]-st[top-1]-(top==2)])%mo;
            sum[top-1]=sum[top-1]+sum[top]*bpow2[st[top]-st[top-1]-(top==2)];
            sum[top-1]=(sum[top-1]>INF?INF+1:sum[top-1]);
            top--;
        }
        pre[top]=(pre[top-1]+rs[top])%mo;
        st[top+1]=i+1;
        for (;j<=m && q[j].r<=i;++j){
            int l=2,r=top,x=1;
            while (l<=r){
                int mid=l+r>>1;
                if (st[mid]<=q[j].l)
                    l=(x=mid)+1;
                else
                    r=mid-1;
            }
            ans[q[j].num]=((pre[top]-pre[x]+mo)+(g[st[x+1]-1]-g[q[j].l-1])*ipow2[q[j].l]%mo+mo)%mo;
        }
    }
    for (int i=1;i<=m;++i)
        printf("%lld\n",ans[i]);
    return 0;
}

개요

...... 너무 요리를 느껴
욕심 질문의 얼굴, 우리는 결론을 감히합니다 ......

추천

출처www.cnblogs.com/jz-597/p/11628758.html