zoukankan      html  css  js  c++  java
  • 2018-2019 ACM-ICPC, Asia Nakhon Pathom Regional Contest-gym 102091 题解

    A. Flying Squirrel

    题意:给你n根柱子,高度分别为a[i]。m次询问:给两个数X,Y。从X出发到Y为止,当Y=0表示可以从X出发,任意位置停止。每一次行走的条件是中间不能有高于或者等于当前柱子高度。

    问我们最多能走多少次?

    首先我们有一个观察,在当前柱子上。我们选择下一根柱子去走的时候,肯定会考虑向左或者向右能走的所有最高的柱子,这相当于从这个点向他们连边。那不妨我们直接考虑从最高的柱子开始走,每次

    向能走到的所有最高的柱子连边,并且递归的去建树,建树的时候顺便把无目的地的答案给处理出来。显然,如果有解的话,我们就把他们之间的深度差输出。

     

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    int st[MAXN][20], lg[MAXN];
    
    int h[MAXN], ans[MAXN], dep[MAXN];
    
    int n, m;
    
    int query(int L, int R){
        int k=lg[R-L+1];
        if(h[st[L][k]]>=h[st[R-(1<<k)+1][k]])return st[L][k];
        else return st[R-(1<<k)+1][k];
    }
    
    int dfs(int L, int R, int d){
        if(L>R)return -1;
    
        int all=0;
        int p=query(L, R);
        dep[p]=d;
        ans[p]=dfs(L,p-1,d+1)+1;
        all=max(all,ans[p]);
    
        while(p<R){
            int q=query(p+1,R);
            if(h[p]!=h[q])break;
    
            int t=dfs(p+1,q-1,d+1)+1;
            ans[p]=max(ans[p],t);
            all=max(all,ans[p]);
            dep[q]=d;
            ans[q]=t;
            p=q;
        }
    
        ans[p]=max(ans[p],dfs(p+1,R,d+1)+1);
        all=max(all,ans[p]);
    
        return all;
    }
    
    int main(){
        n=read();m=read();
    
        for(int i=1;i<=n;++i)h[i]=read(), st[i][0]=i;
        for(int i=2;i<=n;++i)lg[i]=lg[i/2]+1;
    
        for(int j=1;j<=20;++j){
            for(int i=1;i+(1<<j)-1<=n;++i){
                if(h[st[i][j-1]]>=h[st[i+(1<<j-1)][j-1]])st[i][j]=st[i][j-1];
                else st[i][j]=st[i+(1<<j-1)][j-1];
            }
        }
    
        dfs(1,n,0);
    
        while(m--){
            int l, r;
            l=read();
            r=read();
    
            if(!r){
                cout<<ans[l]<<endl;
            }else{
                if(h[l]==h[r]){
                    cout<<"0"<<endl;
                }else{
                    if(h[l]>h[r])swap(l,r);/*ºÃ¶àbug*/
                    int t;
                    if(l<r)t=query(l,r-1);
                    else t=query(r+1,l);
    
                    if(h[t]>=h[r]){
                        cout<<"0"<<endl;
                    }else{
                        cout<<dep[l]-dep[r]<<endl;
                    }
                }
            }
        }
    
        return 0;
    }
    
    /*
    12 8
    2 3 4 4 4 3 3 3 1 2 5 2
    3 0
    4 0
    5 0
    7 0
    7 11
    7 9
    11 1
    9 12
    */
    View Code

     

    B. 留坑,大佬说分类讨论,打表出特殊情况。

    C. Evolution Game

      现在有一些怪物,每一种分别有x个眼睛和y个角。眼睛数量有一个上界N,且每一个眼睛数量都是有其对应的角数量的,你可以以任意一类出生。再给定一个值w,表示眼睛数量的变化范围。i.e. 进化一次,眼睛数量的范围是[x-w,x+w]。还有一个限制条件是每次角的数量只能增加。问最多能进化多少次?

      温暖的签到,记忆化搜索即可。

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 5'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    int h[MAXN];
    
    int f[MAXN];
    
    int n, w;
    
    int dfs(int x){
        if(f[x]!=-1)return f[x];
    
        f[x]=0;
    
        for(int i=max(1,x-w);i<=min(n,x+w);++i){
            if(h[i]>h[x]){
                f[x]=max(f[x],1+dfs(i));
            }
        }
    
        return f[x];
    }
    
    int main(){
        n=read();w=read();
    
        for(int i=1;i<=n;++i){
            h[i]=read();
            f[i]=-1;
        }
    
        int ans=0;
        for(int i=1;i<=n;++i){
            ans=max(ans,dfs(i));
        }
    
        cout<<ans;
        return 0;
    }
    
    /*
    5 5
    5 3 2 1 4
    */
    View Code

    D. Bus Stop

      有一条直线,上面n个点,现在要安排一些点,使得原来的点的左右10单位内至少有一个新安排的点,问最少的新安排上的点的数量?

      从左向右贪心即可。

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define MP make_pair
    #define mid (l+r>>1)
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 2'000'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    int d[MAXN];
    
    void solve(){
        int n=read();
        for(int i=1;i<=n;++i)d[i]=read();
    
        if(n==0){
            cout<<"0"<<endl;
            return;
        }
        int cnt=1;
        int r=d[1]+10;
        int idx=1;
    
        while(1){
            while(abs(d[idx]-r)<=10)++idx;
            if(idx>n)break;
            else{
                r=d[idx]+10;
                ++cnt;
            }
        }
    
        printf("%d
    ",cnt);
    }
    
    int main(){
        int cases;cases=read();
        while(cases--){
            solve();
        }
    
        return 0;
    }
    /*
    2
    5
    1 2 3 200 210
    4
    10 30 80 200
    */
    View Code

    E. How many groups

      给你一个n个数的数组,你可以进行两次操作,包括将数组里的一个数+1或者-1,但不能对同一个元素操作两次。将两个数分成一组的条件是他们之间的差值的绝对值小于2。问其中的最大一组的size是多少?

      设dp[x][i]为以x结尾,且总操作次数为i的组的最大尺寸,然后根据决策去转移就好了。

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 205;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    int f[MAXN][3];
    int temp[MAXN][3];
    int a[MAXN];
    int n;
    
    int main(){
        int t;t=read();
        int kase=1;
        while(t--){
            n=read();memset(f,0,sizeof f);
            for(int i=1;i<=n;++i)a[i]=read();
            sort(a+1,a+n+1);
    
            int ans=1;
    
            for(int i=1;i<=n;++i){
                int x=a[i];
                for(int j=max(x-3,0);j<=x+3;++j){
                    for(int k=0;k<=2;++k){
                        temp[j][k]=f[j][k];
                    }
                }
                for(int j=2;j>=0;--j)f[x][j]=max({temp[x+2][j],temp[x+1][j],temp[x][j],temp[x-1][j],x>=2?temp[x-2][j]:0})+1;
                for(int j=2;j>=1;--j)f[x-1][j]=max({temp[x+1][j-1],temp[x][j-1],temp[x-1][j-1],x-2>=0?temp[x-2][j-1]:0,x-3>=0?temp[x-3][j-1]:0})+1;
                for(int j=2;j>=1;--j)f[x+1][j]=max({temp[x+3][j-1],temp[x+2][j-1],temp[x+1][j-1],temp[x][j-1],temp[x-1][j-1]})+1;
            }
    
            for(int i=1;i<=200;++i)
                for(int j=0;j<=2;++j)ans=max(ans,f[i][j]);
            cout<<"Case "<<kase++<<": "<<ans<<endl;
        }
    
        return 0;
    }
    
    /*
    5
    10
    2 1 7 4 3 8 9 12 13 20
    3
    1 2 3
    4
    1 2 7 8
    3
    10 30 20
    2
    5 5
    
    Case 1: 9
    Case 2: 3
    Case 3: 2
    Case 4: 1
    Case 5: 2
    
    */
    View Code

    F. Lucky Pascal Triangle

      给你一个杨辉三角,问前n行中能被7整除的数的个数是多少。

      首先应该打表找规律,这里只说规律。首先可以发现能被7整除的数是呈块状分布的。第一块从[1,7^1-1],第二块[7^1,7^2-1],第三块[7^2,7^3-1]...。其次,每一块里面都有21块大的块且每一行的个数为等差数列,

      28块为前面所有的行组成的块。我们就能直接预处理出第一块,第二块...,再数出大块里面的块的个数,其他的递归求解。

    #include<bits/stdc++.h>
    
    #define all(x) x.begin(),x.end()
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline LL read(){
        LL res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    template<typename T>
    void chmin(T& a, T b){if(a>b)a=b;}
    
    template<typename T>
    void chmax(T& a, T b){if(b>a)a=b;}
    
    //打表找规律,每一个以7^i为结尾的数量都是有规律的
    //f[i]=f[i-1]*28+(7^(i-1)-1)*7^(i-1)/2*28(具体来讲是考虑28个上一个块。在考虑21个新形成的块)
    
    
    map<LL, LL> H;
    
    LL powmod(LL x, LL y){
        LL res=1;
        while(y){
            if(y&1)
                res=res*x%MOD;
            y>>=1;
            x=x*x%MOD;
        }
        return res;
    }
    
    LL inv2;
    
    void init(){
        LL base=7;
        H[base-1]=0;
        base=49;
        while(base<=(LL)(1e18)){
            LL t=base/7;
            H[base-1]=(28*H[t-1]%MOD+21*inv2%MOD*((t-1)%MOD)%MOD*(t%MOD)%MOD)%MOD;
            base*=7;
        }
    }
    
    LL calc(LL n){
        if(n<=6)return 0;
        LL ans=0;
        LL base=0;
        for(auto it:H){
            LL x=it.fi,y=it.sd;
            if(x<=n){
                ans=y;//先 take care 整块的情况
                base=x;
            }else break;
        }
    
        ++base;
    
        LL a=base;//考虑接下来不为整块的情况
        LL time=1;
    
        LL now=base%MOD*((base-1)%MOD)%MOD*inv2%MOD;
    
        while(a+base<=n){
            ans+=now*time%MOD;//一个大块里面的小块
            ans%=MOD;
    
            ++time;
            ans+=H[base-1]*time%MOD;
            ans%=MOD;
            a+=base;
        }
    
        if(n-a+1==base){
            ans=(ans+(base%MOD)*((base-1)%MOD)%MOD*inv2%MOD*time%MOD)%MOD;//是整块
        }else{
            ans=(ans+((2*base-n+a-2)%MOD+MOD)%MOD*((n-a+1)%MOD)%MOD*inv2*time%MOD)%MOD;//等差数列而已
        }
        ans=(ans+(time+1)*calc(n-a)%MOD)%MOD;
        return ans;
    }
    
    int main(){
        inv2=powmod(2,MOD-2);
        LL cases;cases=read();
        LL kase=1;
        init();
        while(cases--){
            LL n;n=read();
            cout<<"Case "<<kase++<<": "<<calc(n)<<endl;
        }
    
        return 0;
    }
    
    
    /*
    5
    1
    5
    10
    15
    100000
    */
    View Code

    G. Communication

      给n个点的图,求其DAG的节点个数。

      tarjan缩点。

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define MP make_pair
    #define mid (l+r>>1)
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 205;
    const int MAXM = 10'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    #define go(e,u) for(int e=head[u];e;e=Next[e])
    int to[MAXM<<1],Next[MAXM<<1],head[MAXN],tol;
    
    void add_edge(int u,int v){
        Next[++tol]=head[u];to[tol]=v;head[u]=tol;
    //    Next[++tol]=head[v];to[tol]=u;head[v]=tol;
    }
    
    int n, m;
    
    int dfn[MAXN],low[MAXN],dfncnt;
    
    int st[MAXN],top;
    
    int scc[MAXN], sc;
    
    void init(){
        tol=0;top=0;sc=0;
        dfncnt=0;
        memset(dfn,0,sizeof dfn);
        memset(low,0,sizeof low);
        memset(head,0,sizeof head);
        memset(Next,0,sizeof Next);
        memset(to,0,sizeof to);
        memset(scc,0,sizeof scc);
    }
    
    void tarjan(int u){
        dfn[u]=low[u]=++dfncnt;
        st[++top]=u;
    
        go(e,u){
            int v=to[e];
    
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }else if(!scc[v]){
                low[u]=min(low[u],low[v]);
            }
        }
    
        if(low[u]==dfn[u]){
            ++sc;
            while(st[top]!=u){
                scc[st[top]]=sc;
                --top;
            }
            scc[st[top]]=sc;
            --top;
        }
    }
    
    void solve(){
        init();
        n=read();m=read();
        for(int i=1;i<=m;++i){
            int u, v;
            u=read(),v=read();
            ++u,++v;
            add_edge(u,v);
        }
    
        for(int i=1;i<=n;++i)if(!dfn[i])tarjan(i);
    
        cout<<sc<<endl;
    }
    
    int main(){
        int cases;cases=read();
        while(cases--){
            solve();
        }
    
        return 0;
    }
    /*
    3
    6
    2 0 5 5 0
    5
    7 0 1 0 2 1 0 1 3 2 4 3 1 4 2
    3
    4 0 1 0 2 1 0 1 2
    */
    View Code

    H. As rich as Crassus

      给你三个数的立方值关于三个模数的模值,且每一个模值都互质,求这三个数。

      CRT,但是会爆long long,所以需要龟速乘。

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline LL read(){
        LL res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    LL P,mods[4],rem[4];
    
    LL mul(LL x, LL y){
        LL ans=0;
        while(y){
            if(y&1)ans=(ans+x)%P;
            y>>=1;
            x=(x+x)%P;
        }
        return (ans%P+P)%P;
    }
    
    LL exgcd(LL a, LL b, LL& x, LL& y){
        if(!b){x=1;y=0;return a;}
        else{
            LL d=exgcd(b,a%b,y,x);
            y-=(a/b)*x;
            return d;
        }
    }
    
    LL CRT(){
        for(int i=1;i<=3;++i)P*=mods[i];
    
        LL ans=0;
        for(int i=1;i<=3;++i){
            LL x,y;
            LL d=exgcd(P/mods[i],mods[i],x,y);
            x=(x%mods[i]+mods[i])%mods[i];
            if(d!=1)return -1;
            else{
                ans=(ans+mul(mul(P/mods[i],x)%P,rem[i])%P)%P;
            }
        }
        return (ans%P+P)%P;
    }
    
    void solve(){
        P=1;
        for(int i=1;i<=3;++i)mods[i]=read();
        for(int i=1;i<=3;++i)rem[i]=read();
    
        LL ans=CRT();
        if(ans==-1){
            cout<<"-1"<<endl;
        }else{
            LL t=(LL)pow(ans,1.0/3.0);
            if(t*t*t<ans)cout<<t+1<<endl;
            else cout<<t<<endl;
        }
    }
    
    int main(){
        LL cases;cases=read();
        while(cases--){
            solve();
        }
        return 0;
    }
    
    /*
    2
    6 11 19
    5 4 11
    25 36 7
    16 0 6
    */
    View Code

    I. Bowabowaukulipukuli

      防AK题,溜了溜了。

    J. Floating-Point Hazard

      给你一个函数f[x]=(x+1e-15)^(1/3)-(x)^(1/3),给一个下界lo, 一个上界hi,求这个区间内函数值的和。

      这个算式有一些特殊形式,如果分母除一个1e-15,就是求导式。考虑到1e-15已经足够小,这个算式可以用f'[x]*1e-15来代替。求和即可。

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    int lo, hi;
    
    void solve(){
        double ans=0.0;
        for(int i=lo;i<=hi;++i){
            ans+=(1.0/3)*pow(i,-2.0/3.0);
        }
        int cnt=15;
        while(ans<1.0){
            ans*=10.0;
            ++cnt;
        }
        while(ans>10){
            ans/=10;
            --cnt;
        }
    
        printf("%.5fE%.3d
    ",ans,-cnt);
    
    }
    
    int main(){
        while((cin>>lo>>hi)&&(lo+hi)){
            solve();
        }
    
        return 0;
    }
    View Code

    K. The Stream of Corning 2

      给你m次询问或修改,op=1时,给一个值和它的出现时间,消失时间。op=2问当前的rank[k]。

      将询问离线,写一颗权值线段树即可通过(值在1e6内甚至都不用离散化。

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define MP make_pair
    #define mid (l+r>>1)
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    
    namespace FastIO {
        const int SIZE = 1 << 16;
        char buf[SIZE], str[64];
        int l = SIZE, r = SIZE;
        int read(char *s) {
            while (r) {
                for (; l < r && buf[l] <= ' '; l++);
                if (l < r) break;
                l = 0, r = int(fread(buf, 1, SIZE, stdin));
            }
            int cur = 0;
            while (r) {
                for (; l < r && buf[l] > ' '; l++) s[cur++] = buf[l];
                if (l < r) break;
                l = 0, r = int(fread(buf, 1, SIZE, stdin));
            }
            s[cur] = '';
            return cur;
        }
        template<typename type>
        bool read(type &x, int len = 0, int cur = 0, bool flag = false) {
            if (!(len = read(str))) return false;
            if (str[cur] == '-') flag = true, cur++;
            for (x = 0; cur < len; cur++) x = x * 10 + str[cur] - '0';
            if (flag) x = -x;
            return true;
        }
        template <typename type>
        type read(int len = 0, int cur = 0, bool flag = false, type x = 0) {
            if (!(len = read(str))) return false;
            if (str[cur] == '-') flag = true, cur++;
            for (x = 0; cur < len; cur++) x = x * 10 + str[cur] - '0';
            return flag ? -x : x;
        }
    } using FastIO::read;
    
    const int MAXN = 200005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    int st[MAXN],top;
    
    int ans[MAXN];
    
    int T[MAXN<<4];//权值线段树维护排名为第几的值分别有多少个
    
    void update(int nd, int l, int r, int pos, int val){
        if(l==r){
            T[nd]+=val;
            return;
        }
    
        if(pos<=mid)update(lson,l,mid,pos,val);
        else update(rson,mid+1,r,pos,val);
    
        T[nd]=T[lson]+T[rson];
    }
    
    int query(int nd, int l, int r, int k){
        if(l==r){
            return l;
        }
        if(T[lson]>=k)return query(lson,l,mid,k);
        else return query(rson,mid+1,r,k-T[lson]);
    }
    
    struct qq{
        int op,t,val,id;
    }Q[MAXN];
    
    
    bool cmp2(const qq& a, const qq& b){
        if(a.t==b.t)return a.op<b.op;
        return a.t<b.t;
    }
    
    int cnt,cases,kase;
    
    void solve(){
        cnt=top=0;
        int n;read(n);
    
        for(int i=1;i<=n;++i){
            int opop;
            int x,y,z;
            read(opop);
            if(opop==1){
                read(x),read(y),read(z);
                Q[++cnt].op=1;
                Q[cnt].t=x;
                Q[cnt].val=y;
                Q[cnt].id=i;
                Q[++cnt].op=3;
                Q[cnt].t=z;
                Q[cnt].val=y;
                Q[cnt].id=i;
                st[++top]=x;
                st[++top]=z;
            }else{
                read(x),read(y);
                Q[++cnt].op=2;
                Q[cnt].t=x;
                Q[cnt].val=y;
                Q[cnt].id=i;
                st[++top]=x;
            }
        }
    
        sort(st+1,st+top+1);
        top=unique(st+1,st+1+top)-st-1;
        for(int i=1;i<=cnt;++i)Q[i].t=lower_bound(st+1,st+1+top,Q[i].t)-st;
        sort(Q+1,Q+cnt+1,cmp2);
    
        for(int i=1;i<=cnt;++i){
            qq it=Q[i];
            if(it.op==1){
                update(1,1,1e6,it.val,1);
            }else if(it.op==2){
                if(it.val>T[1]){
                    ans[it.id]=-1;
                    continue;
                }
                int rk=query(1,1,1e6,it.val);
                ans[it.id]=rk;
            }else{
                update(1,1,1e6,it.val,-1);
            }
        }
    
        printf("Case %d:
    ",kase);//这里一直T
        for(int i=1;i<=n;++i)if(ans[i]!=0){
            printf("%d
    ",ans[i]);
            ans[i]=0;
        }
    }
    
    int main(){
        read(cases);
        for(kase=1;kase<=cases;++kase){
            solve();
        }
        return 0;
    }
    
    /*
    1
    10
    1 1 10 7
    1 2 9 4
    2 4 1
    1 5 2 6
    2 6 2
    2 7 2
    1 8 2 20
    1 9 1 15
    1 10 3 13
    2 11 3
    */
    View Code

    L. Largest Allowed Area

      给你一个大小为R*C的表格,元素只有0或者1。求最多包含一个1的最大正方形边长。

      前缀和加二分。队友被T的飞起,还好我没做这个题嘿嘿。

    #include<bits/stdc++.h>
    
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define MP make_pair
    #define mid (l+r>>1)
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 1'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    int preSum[MAXN][MAXN];
    
    int R, C;
    
    int get(int x1, int y1, int x2, int y2){
        return preSum[x2][y2]-preSum[x1-1][y2]-preSum[x2][y1-1]+preSum[x1-1][y1-1];
    }
    
    bool check(int len){
        for(int i=1;i<=R-len+1;++i){
            for(int j=1;j<=C-len+1;++j){
                if(get(i,j,i+len-1,j+len-1)<=1)return true;
            }
        }
    
        return false;
    }
    
    void solve(){
        R=read();C=read();
        for(int i=1;i<=R;++i){
            for(int j=1;j<=C;++j){
                preSum[i][j]=read();
            }
        }
    
        for(int i=1;i<=R;++i){
            for(int j=1;j<=C;++j){
                preSum[i][j]+=preSum[i-1][j]+preSum[i][j-1]-preSum[i-1][j-1];
            }
        }
    
        int l=1,r=min(R,C);
        int ans=0;
        while(l<=r){
            if(check(mid)){
                ans=mid;
                l=mid+1;
            }else{
                r=mid-1;
            }
        }
        cout<<ans<<endl;
    }
    
    int main(){
        int cases;cases=read();
        while(cases--){
            solve();
        }
    
        return 0;
    }
    
    /*
    10 20
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
    0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    */
    View Code

     

  • 相关阅读:
    使 Asp.net Core Hosting Bundle 立即生效
    Hosted Services require keep alive
    VS 高级保存选项,解决文件内容编码问题
    asp.net core localhost https 证书
    阿里云K8S下玩.NET CORE 3.1
    cmd 域名生效检测
    c# 通过win32 api 得到指定Console application Content
    .net framework msbuild环境搭建 (不装vs)
    Python常用模块——目录
    Python——爬虫进阶
  • 原文地址:https://www.cnblogs.com/JohnRan/p/12573699.html
Copyright © 2011-2022 走看看