zoukankan      html  css  js  c++  java
  • 题解 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;
    }
    
  • 相关阅读:
    Windows SDK编程(Delphi版) 之 应用基础,楔子
    一个小问题引发的论证思考
    Delphi 组件开发教程指南(7)继续模拟动画显示控件
    用PyInstaller将python转成可执行文件exe笔记
    使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践)
    Microsof Office SharePoint 2007 工作流开发环境搭建
    How to monitor Web server performance by using counter logs in System Monitor in IIS
    LINQ之Order By
    window 性能监视器
    内存泄露检测工具
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/15205420.html
Copyright © 2011-2022 走看看