• [AGC001 D]Arrays and Palindrome


    题意

    对于一对数组(a_i)(b_i),满足(sumlimits_{i=1}^{k_a}a_i=sumlimits_{i=1}^{k_b}b_i=N),而且对于所有长度为(N)的字符串,如果在满足下列两个条件的前提下:

    • 对于前(a_1)个,接下来(a_2)个,再接下去(a_3)个……都是回文串

    • 对于前(b_1)个,接下来(b_2)个,再接下去(b_3)个……都是回文串

    同时还必然满足这个字符串一定全部字符都一样。如果只有原来(a_i)的一个排列,求一种这个(a_i)数组和相应的(b_i)数组。注意可能不存在。

    • (Nleq 10^5)
    • (k_a leq 100)
    • (A_ileq 10^5)

    分析

    先考虑(k_a)比较小的情况,例如(k_a=1),这个时候可以发现我们只需要让回文串错一位就可以了。

    对于(k_a=2),考虑我们从那个中间分隔的点开始往外直接扩展,实际上只要覆盖到两边回文串中间的那个点,然后剩下来的直接随便覆盖就可以了(因为就这一些已经将两个回文串“连接”在了一起),这是一个思路,但是比较难以实现。

    更加直接的思路(按照题解),还是按照错位,我们考虑实际上只需要将中间那个分割点向左边移动一下,那也是能够相应建立关系的。

    按照这个思路,我们应该可以进一步地考虑推广!我们应该可以按照这个思路,只需要取(b={a_1-1,a_2,cdots,a_{k_a-1},a_{k_a}+1}),这种答案的构造方法,除非是中间的数是偶数,否则都是可以的。

    那么当存在大量偶数的时候有没有可能构造出一个相应的解呢?我们考虑设(a)里面偶数有(O_a)个,(b)里面偶数有(O_b)个,那么边数是(frac{N-O_a}{2}+frac{N-O_b}{2}),考虑如果我们要让这(N)个点连通,我们肯定至少需要(N-1)条边,那么也就是(frac{N-O_a}{2}+frac{N-O_b}{2}geq N-1),这个不等式算出来是(O_a+O_bleq 2)……于是我们发现不可能偶数多于(2)个。如果满足的话那一定可以将这两个偶数调到最前和最后。

    那么我们只要扫一遍就可以得到了。回顾一下思路,我们从(k_a=1)的情况推出了错位的思路,然后进一步推广到了一般情况,同时对于一种看上去比较特殊的情况得出了解。最后,我们证明了剩下的情况没有解,实际上也就是说因为有偶数,所以相当于要浪费一部分边去专门将偶数导走,然后整个图就无法导通。

    注意在写的时候有可能会出现减出(0)的情况,所以需要再判一下边界情况。

    # include <bits/stdc++.h>
    # define il inline
    # define fi first
    # define se second
    # define pb push_back
    # define mem(x,v) memset(x,v,sizeof x)
    # define rep(i,x,y) for(int i=x;i<=y;++i)
    # define re(i,x,y) for (int i=x;i<y;++i)
    using namespace std;
    typedef long long ll;
    il ll read(){
    	ll x=0; char c=getchar();
    	for(;c<'0'||c>'9';c=getchar());
    	for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
    	return x;
    }
    const int maxm = 100+10;
    int n,m;
    int a[maxm];
    vector<int> b;
    int main(){
    	n=read(); m=read();
    	rep(i,1,m) a[i]=read();
    	if (m == 1){
    		b.pb(1); b.pb(n-1);
    	}
    	else{
    		int cnt = 0;
    		rep(i,1,m) cnt += a[i] % 2;
    		if (cnt > 2){
    			puts("Impossible"); return 0;
    		}
    		rep(i,2,m-1)
    			if (a[i]%2==1){
    				if (a[1]%2==0)swap(a[1],a[i]);
    				else swap(a[m],a[i]);
    			}
    		b.pb(a[m]+1);
    		for (int i=m-1;i>1;--i) b.pb(a[i]);
    		b.pb(a[1]-1);
    	}
    	rep(i,1,m) printf("%d ",a[i]); printf("
    ");
    	int bs=b.size();
    	if (b[bs-1] == 0)--bs;
    	printf("%d
    ",bs);
    	for (int i=bs-1;i>=0;--i) printf("%d ",b[i]); printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    virtualenv+pyenv管理python工作环境
    OpenStack 安装:neutron服务
    OpenStack 安装:nova服务
    node.js工具 nodemon使用
    js的数据类型及数据类型检测
    Git 工具
    Object.prototype.toString.call() 、 instanceof 以及 Array.isArray()判断数组的方法的优缺点
    重绘和回流及优化
    jsapi 调起微信支付的的踩坑
    总结Jquery中获取自定义属性使用.attr()和.data()以及.prop()的区别
  • 原文地址:https://www.cnblogs.com/wendavid/p/8982266.html
Copyright © 2020-2023  润新知