1. 程式人生 > >Codeforces Round #251(Div. 2) 439C. Devu and Partitioning of the Array 構造

Codeforces Round #251(Div. 2) 439C. Devu and Partitioning of the Array 構造

C. Devu and Partitioning of the Array time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output

Devu being a small kid, likes to play a lot, but he only likes to play with arrays. While playing he came up with an interesting question which he could not solve, can you please solve it for him?

Given an array consisting of distinct integers. Is it possible to partition the whole array into 

k disjoint non-empty parts such that p of the parts have even sum (each of them must have even sum) and remaining k - p have odd sum? (note that parts need not to be continuous).

If it is possible to partition the array, also give any possible way of valid partitioning.

Input

The first line will contain three space separated integers n, k, p (1 ≤ k ≤ n ≤ 105; 0 ≤ p ≤ k). The next line will contain n space-separated distinct integers representing the content of array a: a1, a

2, ..., an (1 ≤ ai ≤ 109).

Output

In the first line print "YES" (without the quotes) if it is possible to partition the array in the required way. Otherwise print "NO" (without the quotes).

If the required partition exists, print k lines after the first line. The ith of them should contain the content of the ith part. Print the content of the part in the line in the following way: firstly print the number of elements of the part, then print all the elements of the part in arbitrary order. There must be exactly p parts with even sum, each of the remaining k - p parts must have odd sum.

As there can be multiple partitions, you are allowed to print any valid partition.

Examples input
5 5 3
2 6 10 5 9
output
YES
1 9
1 5
1 10
1 6
1 2
input
5 5 3
7 14 2 9 5
output
NO
input
5 3 1
1 2 3 7 5
output
YES
3 5 1 3
1 7
1 2

題意:

出n個數,將n個數分成k個不相交集合,並且其中恰好有p個集合的元素之和為偶數,輸出分解方案。


題解:

題目要求p個集合偶數和,那麼就有q=k-p個集合奇數和。

奇+奇=偶

奇+偶=奇

偶+偶=偶

所以和為奇數的集合裡必須包含奇數個奇數,故第一個無解的情況為:奇數的個數<q。

對於多出來的奇數,可以偶數個奇陣列成偶數,以此來不擾亂偶數的組合,但是在組成完成q個奇數集合後,剩下的奇數如果是奇數個,那麼就是第二個無解的情況:

(奇數的個數-q)%2!=0.

如果按照上面的方法組成的集合個數小於k,則也是無解。

接下來就是構造,先處理奇數,再處理偶數就好了。


/****************
*PID:439c div2
*Auth:Jonariguez
*****************
*/
#define lson k*2,l,m
#define rson k*2+1,m+1,r
#define rep(i,s,e) for(i=(s);i<=(e);i++)
#define For(j,s,e) For(j=(s);j<(e);j++)
#define sc(x) scanf("%d",&x)
#define In(x) scanf("%I64d",&x)
#define pf(x) printf("%d",x)
#define pfn(x) printf("%d\n",(x))
#define Pf(x) printf("%I64d",(x))
#define Pfn(x) printf("%I64d\n",(x))
#define Pc printf(" ")
#define PY puts("YES")
#define PN puts("NO")
#include <stdio.h>
#include <string.h>
#include <string>
#include <math.h>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef __int64 LL;
typedef int Ll;
Ll quick_pow(Ll a,Ll b,Ll MOD){a%=MOD;Ll res=1;while(b){if(b&1)res=(res*a)%MOD;b/=2;a=(a*a)%MOD;}return res;}

const int maxn=100000+10;
int a[maxn];
vector<int> odd,eve;

int main()
{
    int i,j,n,k,p;
    while(scanf("%d%d%d",&n,&k,&p)!=EOF){
        odd.clear();eve.clear();
        int ji=0,ou=0;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(a[i]&1){
                ji++;odd.push_back(a[i]);
            }else {
                ou++;eve.push_back(a[i]);
            }
        }
        int q=k-p;
        if(ji<q || ji>=q && (ji-q)&1){
            puts("NO");continue;
        }
        if(q+(ji-q)/2+ou<k){
            puts("NO");continue;
        }
        PY;
        if(p==0){
            for(i=0;i<k-1;i++)
                printf("1 %d\n",odd[i]);
            printf("%d",n-k+1);
            for(;i<odd.size();i++)
				printf(" %d",odd[i]);
            for(i=0;i<eve.size();i++)
                printf(" %d",eve[i]);
            puts("");continue;
        }else if(q==0){
            if(eve.size()>=k-1){
                for(i=0;i<k-1;i++)
                    printf("1 %d\n",eve[i]);
                printf("%d",n-k+1);
                for(;i<eve.size();i++)
                    printf(" %d",eve[i]);
                for(i=0;i<odd.size();i++)
                    printf(" %d",odd[i]);
                puts("");continue;
            }else {
                int cnt=0;
                for(i=0;i<eve.size();i++){
                    printf("1 %d\n",eve[i]);
                    cnt++;
                }
                int temp=eve.size();
                j=0;
                for(i=temp+1;i<=k-1;i++){
                    printf("2 ");
                    printf("%d %d\n",odd[j],odd[j+1]);
                    cnt+=2;j+=2;
                }
                if(n-cnt>0){
                    printf("%d",n-cnt);
                    for(;j<odd.size();j++)
                        printf(" %d",odd[j]);
                    puts("");
                }
                continue;
            }
        }
        int cnt=0;
        for(i=0;i<q;i++){
            printf("1 %d\n",odd[i]);
            cnt++;
        }
        if(ou<p){
            for(i=0;i<eve.size();i++){
                printf("1 %d\n",eve[i]);
                cnt++;
            }
            int c=eve.size()+1;
            for(i=q;c<p && i<odd.size();i+=2){
                printf("2 %d %d\n",odd[i],odd[i+1]);
                c++;cnt+=2;
            }
            printf("%d",n-cnt);
            for(;i<odd.size();i++)
                printf(" %d",odd[i]);
            puts("");
        }else {
            for(i=0;i<p-1;i++){
                printf("1 %d\n",eve[i]);cnt++;
            }
            printf("%d",n-cnt);
            for(;i<eve.size();i++)
                printf(" %d",eve[i]);
            for(i=q;i<odd.size();i++)
                printf(" %d",odd[i]);
            puts("");
        }
    }
    return 0;
}

/*
8 4 4
1 1 1 1 1 1 1 1

*/