AtCoderグランドコンテスト問題の解決015

ポータル

\(\)

最大値と最小値を達成することが見出され、次いで、その任意の中間を表すことができます。

typedef long long ll;
int n,a,b;ll res;
int main(){
    scanf("%d%d%d",&n,&a,&b);
    if(a>b||n==1&&a!=b)return puts("0"),0;
    res=(a+b+1ll*(n-2)*b)-(a+b+1ll*(n-2)*a)+1;
    printf("%lld\n",res);
    return 0;
}

\(Bの\)

番号を取ると、二回にログオンする必要性を計算しました。

typedef long long ll;
const int N=1e5+5;
char s[N];int n;ll res,sum;
int main(){
    scanf("%s",s+1),n=strlen(s+1);
    fp(i,1,n)sum+=(s[i]=='U'?n-i:i-1);
    res=(1ll*n*(n-1)-sum)*2+sum;
    printf("%lld\n",res);
    return 0;
}

\(C \)

うまく維持するために、その後、通信ブロック数は、それぞれ、点の総数マイナスエッジの数である、木に似た何かを見つけることは困難ブルードット

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int N=2005;
char mp[N][N];int r[N][N],c[N][N],s[N][N],n,m,q;
inline int qs(R int x,R int y,R int xx,R int yy){
    return s[xx][yy]-s[x-1][yy]-s[xx][y-1]+s[x-1][y-1];
}
inline int qr(R int x,R int y,R int xx,R int yy){
    return r[xx][yy]-r[x-1][yy]-r[xx][y-1]+r[x-1][y-1];
}
inline int qc(R int x,R int y,R int xx,R int yy){
    return c[xx][yy]-c[x-1][yy]-c[xx][y-1]+c[x-1][y-1];
}
int main(){
    scanf("%d%d%d",&n,&m,&q);
    fp(i,1,n){
        scanf("%s",mp[i]+1);
        fp(j,1,m)s[i][j]=(mp[i][j]=='1')+s[i-1][j]+s[i][j-1]-s[i-1][j-1];
    }
    fp(i,1,n)fp(j,1,m-1){
        r[i][j]=r[i-1][j]+r[i][j-1]-r[i-1][j-1]+(mp[i][j]=='1'&&mp[i][j+1]=='1');
    }
    fp(i,1,n-1)fp(j,1,m){
        c[i][j]=c[i-1][j]+c[i][j-1]-c[i-1][j-1]+(mp[i][j]=='1'&&mp[i+1][j]=='1');
    }
    for(R int x,y,xx,yy;q;--q){
        scanf("%d%d%d%d",&x,&y,&xx,&yy);
        printf("%d\n",qs(x,y,xx,yy)-qr(x,y,xx,yy-1)-qc(x,y,xx-1,yy));
    }
    return 0;
}

\(D \)

まず、場合\(A = B \)答えは(1 \)を\ので、私たちはその前提と\(B> \)

最初の検索\(A、B \)異なるビットバイナリセンス\(R \) 次いでビットの前部が使用されていないが削除することができます

我々は、2つの組に分割:\([A、2 X 、Y ^ R):2 ^ R、B] \)

セット\(K \)\(Bの\)まず、以下である\(R&LT \)とされている\(1 \)が、バイナリビット

  • のみ\(X- \) を示す\([Aは、R ^ 2)\) 直接選挙の数に相当する)、及びこれらのみの最小数が示されている(それはのように表すことができる\(A \) 最大数\(2-R&LT ^ 1 \)

  • のみ\(Yは、\)を示すことができるだけ\([R&LT ^ 2は、R ^ 2 + 2 ^ {-1}。1 + K] \) 各ので\(2 ^ R + 2 ^ I \ (Iはで必ずしも存在している)のLeq K \ \(Y \) されています

  • 同時\(X- \)\(Y \) を示す\([R&LT ^ 2 + Aは、R + 2 ^ {-1}。1] \) 直接選挙\(2 ^ Rの\)\ (X \)での数、およびだけでは、これら(同上)を示し、

その後、我々は直接追加\を([A、R&LT + 2 ^ {-1}。1] \)、[OK]をクリックし文\(2 ^ R + 2 ^ {K + 1} -1 \) と\(2 ^ R + \)のサイズだけで罰金

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
typedef long long ll;
ll a,b,res;
int main(){
    scanf("%lld%lld",&a,&b);
    if(a==b)return puts("1"),0;
    R int r,k;
    for(r=59;(a>>r&1)==(b>>r&1);--r);
    a&=(1ll<<(r+1))-1,b&=(1ll<<(r+1))-1;
    res=(1ll<<(r+1))-a;
    for(k=r-1;(~k)&&(b>>k&1^1);--k);
    if(a>(1ll<<(k+1)))res-=a-(1ll<<(k+1));
    printf("%lld\n",res);
    return 0;
}

\(E \)

私は愚かな人々を行う必要があり、データ構造の一種である......

私は私がそれを言うの問題に対する解決策の実践についてお話しましょう

まず、すべての間違いの数に応じて十分に長い時間、相対的な順序の後に\(V \)表記、ソート後の相対的な順序\(id_i \)で表さ\(V \)ソートした後、\(私は\)に位置して

私たちは、最初に想定し\(私は\) その後のために、選択された\(X - jが<X_I \)\(v_j> V_I \)ポイント\(J \) 確かに通過します\(私は\します)彼らが選択されているように、プレス\(V \)ソートした後、すべての\(I、Jの\)ポイントの間で選択されます

それぞれについて我々\(Iは\) 最大の計算\(id_jを\)\(X - jが<X_I \)として示される、\(R_iを\)は、すべての\([id_i、ID_ {R_iを }] \) ポイントとの間で選択されます。同様に定義します\(L_iを\)を見つけるのは簡単\(L、Rの\)単調にドロップされます

次いで、所与のに問題\(N- \)間隔と左右端点が単調下降ことを保証するために、そのような被覆の数選択\は([1、N-] \) 我々は覚えている(F_iと\)\表す\([1 、私は] \)プログラム番号でカバーされており、プレフィックスは転送し、最適化することができます

私はバックで練習します

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
    R int res=1;
    for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    return res;
}
const int N=2e5+5;
struct node{
    int x,v;
    inline bool operator <(const node &b)const{return x<b.x;}
}a[N];
int id[N],l[N],r[N],f[N],n;
inline bool cmp(const int &x,const int &y){return a[x].v<a[y].v;}
int main(){
    scanf("%d",&n);
    fp(i,1,n)scanf("%d%d",&a[i].x,&a[i].v),id[i]=i;
    sort(a+1,a+1+n),sort(id+1,id+1+n,cmp);
    fp(i,1,n)l[id[i]]=r[id[i]]=i;
    fp(i,2,n)cmax(r[i],r[i-1]);
    fd(i,n-1,1)cmin(l[i],l[i+1]);
    f[0]=1;
    for(R int i=1,j=0,sum=1;i<=n;++i){
        while(j<l[i]-1)sum=dec(sum,f[j++]);
        upd(f[r[i]],sum),upd(sum,sum);
    }
    printf("%d\n",f[n]);
    return 0;
}

初回の\(X \)のソート、\(私は\) それが最初に選択された場合に確実に選択され、そうでない場合は、聞かせて\(ラス\)\(NXT用\)は、前に選択しました後者が選択され、設定さ(Lの\)\を表す\([1、ラス] \ ) のすべての最高速度を、\(R&LTの\)を表す\([NXT、N]を\ ) すべての最小速度で値は、その後、\は、(私は\)と場合にのみ場合に選択されません\(私は[L、R&LT] \で\)それはどちらも、それは選択させるいくつかのキャッチは、それが不可能であることは上記からではありません(バック、彼らが選択されているリードの数をキャッチします)

私たちは、セット\(las_i \)はその意味(私は\)\選挙後、最大の\(J \)ように\(J \)選択された後に\([J + 1、I -1] \) この間隔を各番号が選択されます、あなたは裁判官がライン上のツリーについての会長を宣告するとき、半分することができます

次に、設定([I] \ F)\を表す\(Iは\)プログラムの数を選択する必要があり、その後、選択された一つがされてもよい\([ラス[i]は、 I-1] \) 番号のいずれかを、接頭辞と最適化のように見えます

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
    R int res=1;
    for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    return res;
}
inline int max(R int x,R int y){return x>y?x:y;}
inline int min(R int x,R int y){return x<y?x:y;}
const int N=2e5+5,M=N*35,inf=0x3f3f3f3f;
int ls[M],rs[M],sz[M],rt[N],nd;
void ins(int &p,int q,int l,int r,int x){
    p=++nd,ls[p]=ls[q],rs[p]=rs[q],sz[p]=sz[q]+1;
    if(l==r)return;int mid=(l+r)>>1;
    x<=mid?ins(ls[p],ls[q],l,mid,x):ins(rs[p],rs[q],mid+1,r,x);
}
int query(int p,int q,int l,int r,int ql,int qr){
    if(!(sz[p]-sz[q])||ql<=l&&qr>=r)return sz[p]-sz[q];
    int mid=(l+r)>>1,res=0;
    if(ql<=mid&&query(ls[p],ls[q],l,mid,ql,qr))return 1;
    if(qr>mid&&query(rs[p],rs[q],mid+1,r,ql,qr))return 1;
    return 0;
}
struct node{
    int x,v;
    inline bool operator <(const node &b)const{return x<b.x;}
}a[N];
int b[N],las[N],f[N],mx[N],mn[N],sum[N];
int n;
inline int find(R int pos){
    R int l=0,r=pos-1,ans=pos-1,mid;
    while(l<=r){
        mid=(l+r)>>1;
        if(mid==pos-1||mx[mid]+1>mn[pos]-1||!query(rt[pos-1],rt[mid],1,n,mx[mid]+1,mn[pos]-1))
            ans=mid,r=mid-1;
        else l=mid+1;
    }
    return ans;
}
int main(){
//  freopen("testdata.in","r",stdin);
    scanf("%d",&n);
    fp(i,1,n)scanf("%d%d",&a[i].x,&a[i].v),b[i]=a[i].v;
    sort(a+1,a+1+n),sort(b+1,b+1+n);
    fp(i,1,n){
        a[i].v=lower_bound(b+1,b+1+n,a[i].v)-b;
        ins(rt[i],rt[i-1],1,n,a[i].v);
    }
    mx[0]=0;fp(i,1,n)mx[i]=max(mx[i-1],a[i].v);
    mn[n+1]=inf;fd(i,n,1)mn[i]=min(mn[i+1],a[i].v);
    fp(i,1,n+1)las[i]=find(i);
    f[0]=sum[0]=1;
    fp(i,1,n+1){
        f[i]=dec(sum[i-1],(las[i]?sum[las[i]-1]:0));
        sum[i]=add(sum[i-1],f[i]);
    }
    printf("%d\n",f[n+1]);
    return 0;
}

\(F \)

結論不滅のタイトル

以下セット\(F(x、y)は 、\) を表し\(X、Y \)デフォルトにより除去し、分割されたステップ数\(X <Yの\)を

我々は最初のフィボナッチ数を考慮して、定義\を(F. [0] = F. [1] = 1 \) 見つけるのは簡単\(F(F [I] 、F [I + 1])= iは\) とすべてのために\(F(A、B)= Iが\)がある(\ \ GEQ F. [I]、B \ GEQ F.は[Iは、+ 1] \) だから、最初の質問が出て得ることは非常に簡単です

我々は多くの定義\(F(a、b)は \) 場合にのみ不在良好である\(C <、D < B \) と\(F(C、D) > F(、 B)\) そして答えは唯一のかなりの数に貢献します

我々は多くの定義\(fは(B) \) 、優れている場合に限り場合\(F(A、B)= K \) 次いで\(、Bの\の当量F [K + 2 ] + F [K-1] \)

一つの結論:分割して取り外すのは良い番号の後の任意の時間にはかなりの数になります

仮定して、矛盾を考える\(A = Y、X B = Pyと+ \) および\(F(A、B)= K + 1 \)分割がなった後、次に除去\((X、Y)\ ) 場合\((x、y)は\ ) ペアのかなりの数ではない\(Y> F. [K + 2] + F. [1-K] \)それによって

\ [\ A&{整列}始める= Y> F [K + 2] \\&X> F [k]は\\&B = PY + X \のGEQのY + X> F [K + 2] + F [K-1 ] + F [K] = F [K + 3] \\ \端{整列} \]

そこ\(C = F. [K + 2]、D = F. [K + 3] \) そう\(F(C、D)> F(A、B)\) その\((、 B)\)不一致のかなりの数です

だから私たちはいつでも分割後の削除のかなりの数が合うように言った(あまりにも多くの優れたの数、および優れた多くの後になっていないだろうことを証明した(F(a、b)は\ = K \ アウトスタンディング数の数です)\ \(O(K) )?私は証明していません

その後、我々はすべてのテーブルを打つ\(F(a、b)は =のk \) のかなりの数を生成するために、かなりの数で行くように頼まれると、うまく出てくるのスパーリングの優れた数の

//quming
#include<bits/stdc++.h>
#define R register
#define pb emplace_back
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=1e9+7;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
    R int res=1;
    for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    return res;
}
typedef long long ll;
const int N=105,M=90;
struct node{
    ll x,y;
    inline node(R ll xx,R ll yy):x(xx),y(yy){}
};vector<node>g[N];
ll f[N],n,m,T,res,cnt;
int main(){
    f[0]=f[1]=1;fp(i,2,M)f[i]=f[i-1]+f[i-2];
    g[1].pb(node(1,2)),g[1].pb(node(1,3)),g[1].pb(node(1,4));
    fp(i,1,M-3){
        for(auto v:g[i]){
            R ll x=v.y,y=v.x+x;
            while(y<=f[i+3]+f[i])g[i+1].pb(node(x,y)),y+=x;
        }
    }
    scanf("%lld",&T);
    while(T--){
        scanf("%lld%lld",&n,&m);if(n>m)swap(n,m);
        for(cnt=1;f[cnt+1]<=n&&f[cnt+2]<=m;++cnt);
        if(cnt==1){printf("%lld %lld\n",cnt,n*m%P);continue;}
        res=0;
        for(auto v:g[cnt-1]){
            R ll x=v.x,y=v.y;
            if(y<=n)res+=(m-x)/y%P;
            if(y<=m)res+=(n-x)/y%P;
            res%=P;
        }
        printf("%lld %lld\n",cnt,res);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/yuanquming/p/11561324.html
おすすめ