• 题解 CF1556E 【Equilibrium】


    题目意思:

    (n) 组数 (a_1,a_2,cdots,a_n)(b_1,b_2,cdots,b_n)(q) 次独立的询问,每次询问区间 (lsim r),求多少次“平衡操作”使得每个满足 (lle ile r)(i) 都有 (a_i=b_i),无法完成输出 -1

    平衡操作指的是给出一个长度为偶数位置序列 (lle pos_1<pos_2<cdots<pos_kle r),进行操作:(a_{pos_1},a_{pos_3},a_{pos_5},cdots) 加上 1,(b_{pos_2}) 加上 1。

    我们发现如果 (a_i) 减去 1,那么就相当于是 (a_i-b_i) 减去 (1)。我们发现如果 (b_i) 减去 1,那么就相当于是 (a_i-b_i) 加上 (1),最终要让每个满足 (lle ile r)(i) 都有 (a_i-b_i=0)

    我们去观察它的操作序列,实际上这些元素是分成了若干个组,比如 (po s_1)(pos_2)

    我们把 (a_i-b_i) 这个东西前缀和一下,(s_i) 表示 ((a_1-b_1)+(a_2-b_2)+cdots+(a_i-b_i)),就会发现每组操作 (pos_1,pos_2),相当于是在前缀和上区间加 (s_{pos_1}sim s_{pos_2-1}) 区间加 1。

    -1 就是 2 种情况:

    1. (s_r e s_{l-1})
    2. (maxlimits_{i=l}^{r}{s_i}>s_{l-1}) (因为是区间加 1)

    答案是 (s_{l-1}-minlimits_{i=l}^{r}{s_i}),都不是很困难。

    区间查询 (max)(min),用 ST 表实现即可。

    #include<bits/stdc++.h>
    #define int long long
    #define log(a) cerr<<"[DEBUG] "<<#a<<'='<<(a)<<" @ line "<<__LINE__<<endl
    using namespace std;
    typedef long long LL;
    template<typename T>void chkmax(T&x,T y){x=max(x,y);}
    template<typename T>void chkmin(T&x,T y){x=min(x,y);}
    template<typename T>inline void read(T &FF){
        T RR=1;FF=0;char CH=getchar();
        for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
        for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
        FF*=RR;
    }
    const int N=1e5+10,M=25;
    int a[N],f[N],lg[N],mxn[M][N],mnn[M][N];
    pair<int,int>query(int l,int r){
    	int len=lg[r-l+1];
    	return make_pair(max(mxn[len][l],mxn[len][r-(1<<len)+1]),min(mnn[len][l],mnn[len][r-(1<<len)+1]));
    }
    signed main(){
    	int n,q;
    	read(n);read(q);
    	for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;
    	for(int i=1;i<=n;i++)read(a[i]);
    	for(int i=1,x;i<=n;i++){
    		read(x);
    		a[i]-=x;
    		f[i]=f[i-1]+a[i];
    	}
    	// cout<<"->f";for(int i=1;i<=n;i++)cout<<f[i]<<" ";cout<<endl;
    	for(int i=0;i<=20;i++)
    		for(int j=1;j+(1<<i)-1<=n;j++)
    			if(i==0)mxn[i][j]=mnn[i][j]=f[j];
    			else{
    				mxn[i][j]=max(mxn[i-1][j],mxn[i-1][j+(1<<(i-1))]);
    				mnn[i][j]=min(mnn[i-1][j],mnn[i-1][j+(1<<(i-1))]);
    			}
    	// log(mnn[2][2]);
    	while(q--){
    		int l,r;
    		read(l);read(r);
    		pair<int,int>a=query(l,r);
    		// log(a.first);log(a.second);
    		if(f[r]!=f[l-1]||a.first>f[l-1])puts("-1");
    		else cout<<f[l-1]-a.second<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Elementui:选择框
    Cesium之Cesium3DTileStyle
    Cesium粒子系统:雨雪云效果
    Cesium之3dtiles模型选择问题
    3dtiles贴地
    Android ListView异步加载图片
    Android的硬件加速
    Android ANR
    每天一点Linux 查看Ubuntu的版本号
    Android log system
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/15205420.html
Copyright © 2020-2023  润新知