• CF1562 D1. Two Hundred Twenty One (easy version)


    https://codeforces.com/problemset/problem/1562/D1

    题意:
    给出一个由1和-1构成的序列,有若干次询问,每次询问一个区间,问最少删除几个数,满足区间内剩下的序列的奇数项减去偶数项=0

    结论:
    1、若区间原本的奇数项-偶数项的和=0,答案是0
    否则,
    2、若区间长度为奇数,答案是1
    3、若区间长度是偶数,答案是2

    2的证明:
    (b_i)表示一个长度为奇数的区间去掉第i项之后的奇数项减去偶数项
    因为(b_i)有偶数个数,所以(b_i)一定是偶数
    若第(i)个数=第(i+1)个数,那么(b_i=b_{i+1})。这个好理解,因为相邻的这2个数是一个样的,去掉谁都一样。
    若第(i)个数( eq)(i+1)个数,那么(|b_i-b_{i+1}|=2)。这是因为去掉这2个数中的某个数,对于(i)前面和(i+1)后面的数的影响都是一样的。又因为他们两个不一样,所以差值是2。
    接下来我们的目标是证明必然存在一个(i)满足(b_i=0)

    设区间长度为(n)
    (b_1)或者(b_n=0),那么就删除第(1)或者第(n)个数即可
    (b_1)(b_n)( eq0),设(x)表示第2个数-第3个数+第4个数-第5个数……,则(x)必然是奇数
    (b_1=-x±1)(b_n=x±1),可以得出(b_1)(b_n)不会同时大于0或者同时小于0
    (b_1)(b_n)必然一正一负
    而又因为(|b_i-b_{i+1}|=2)(b_i)一定是偶数,所以必然存在一个(i)满足(b_i=0)

    3的证明:
    (b_i)表示一个长度为偶数的区间去掉第i项之后的奇数项减去偶数项
    因为(b_i)有奇数个数,所以(b_i)一定是奇数
    所以删除1个肯定不行
    删除1个之后区间长度变为奇数,由结论2可得,再删除1个必然有解

    #include<bits/stdc++.h>
    
    #define N 300002
    
    char s[N]; 
    int a[N];
    
    int sum(int l,int r)
    { 
    	if(l&1) return a[r]-a[l-1];
    	return a[l-1]-a[r];
    }
    
    int main()
    {
    	int T,n,m,l,r;
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d%s",&n,&m,s+1);
    		for(int i=1;i<=n;++i) a[i]=s[i]=='+' ? 1 : -1;
    		for(int i=1;i<=n;++i) 
    			if(i&1) a[i]=a[i-1]+a[i];
    			else a[i]=a[i-1]-a[i];
    		while(m--)
    		{
    			scanf("%d%d",&l,&r);
    			if(!sum(l,r)) printf("0
    ");
    			else if((r-l)&1) printf("2
    ");
    			else printf("1
    ");
    		}
    	}
    }
    
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    kubernetes的设计理念
    kubernetes整体架构
    kubernetes的起源
    云原生有未来吗?
    cloud native
    kata containers
    go特性
    开源在线分析诊断工具Arthas(阿尔萨斯)--总结
    javaAgent介绍
    oracle函数操作
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15234002.html
Copyright © 2020-2023  润新知