6374. [2019年10月4日]ウォードNOIP2019アナログ[生と死の領域]

タイトル

効果の対象に

あなたの列数を与えるために、それぞれが隣接する2つの数字を選ぶことができます\(X \)\(Y \) 本来の位置での削除や挿入\(X + 2Y \)
たびにクエリ間隔、上記の操作の間隔。最後に残った数が最大数である検索。
答えは、モジュロを必要とします。


歴史上のものがたり

この問題を参照してください、最初に考えたものです。この問題は、最大の前方に配置する必要があるが、また、法とするので、それは貪欲でなければなりません。
しかし、ない......
\(O(3 ^ N-)\)暴力が間隔に直接戦ったことができます\(DP \) しかし、私は再生できませんでした。
実際には、最大のボトルネックは、私は、それは......爆破されますが数が多すぎる、大きさ以上のものを必要とすることで
、この問題自体は非友好的な暴力の問題に直面している......


正解

私は興味深い特性でゲームを発見したときに実際には、:
私たちは、全体の範囲は、2つのセクションに分かれていて、係数の後ろ部分には、2を掛けた後、双方は、再帰プロセスを継続動作させます。
仮定し、見つけやすい(\ 2 ...... {K_I} \の ) 最初のため(私は\)\各項の係数、\(1 \のLeq K_I \のLeq 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 + 2 ^のxB + 2 ^ {X + Y C} \) および分割がなった後\(2 ^ B + YC \) それが分割されている場合、それはなり\(B + C \) ..
各乗じ\(X ^ 2 \) プラス\(A \) それぞれ、それがなる(A + 2 ^のxB + \ 2 ^ {X + Y} C \) と\(A + 2 ^のxBを+ 2 ^クロスシー\)
ように前者は、最適化されなければならないので、\(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