Codeforces Problemset problem 1120 A Diana and Liana —— 尺取

At the first holiday in spring, the town Shortriver traditionally conducts a flower festival. Townsfolk wear traditional wreaths during these festivals. Each wreath contains exactly k flowers.

The work material for the wreaths for all n citizens of Shortriver is cut from the longest flowered liana that grew in the town that year. Liana is a sequence a1, a2, …, am, where ai is an integer that denotes the type of flower at the position i. This year the liana is very long (m≥n⋅k), and that means every citizen will get a wreath.

Very soon the liana will be inserted into a special cutting machine in order to make work material for wreaths. The machine works in a simple manner: it cuts k flowers from the beginning of the liana, then another k flowers and so on. Each such piece of k flowers is called a workpiece. The machine works until there are less than k flowers on the liana.

Diana has found a weaving schematic for the most beautiful wreath imaginable. In order to weave it, k flowers must contain flowers of types b1, b2, …, bs, while other can be of any type. If a type appears in this sequence several times, there should be at least that many flowers of that type as the number of occurrences of this flower in the sequence. The order of the flowers in a workpiece does not matter.

Diana has a chance to remove some flowers from the liana before it is inserted into the cutting machine. She can remove flowers from any part of the liana without breaking liana into pieces. If Diana removes too many flowers, it may happen so that some of the citizens do not get a wreath. Could some flowers be removed from the liana so that at least one workpiece would conform to the schematic and machine would still be able to create at least n workpieces?

Input
The first line contains four integers m, k, n and s (1≤n,k,m≤5⋅105, k⋅n≤m, 1≤s≤k): the number of flowers on the liana, the number of flowers in one wreath, the amount of citizens and the length of Diana’s flower sequence respectively.

The second line contains m integers a1, a2, …, am (1≤ai≤5⋅105) — types of flowers on the liana.

The third line contains s integers b1, b2, …, bs (1≤bi≤5⋅105) — the sequence in Diana’s schematic.

Output
If it’s impossible to remove some of the flowers so that there would be at least n workpieces and at least one of them fullfills Diana’s schematic requirements, output −1.

Otherwise in the first line output one integer d — the number of flowers to be removed by Diana.

In the next line output d different integers — the positions of the flowers to be removed.

If there are multiple answers, print any.

Examples
inputCopy
7 3 2 2
1 2 3 3 2 1 2
2 2
outputCopy
1
4
inputCopy
13 4 3 3
3 2 6 4 1 4 4 7 1 3 3 2 4
4 3 4
outputCopy
-1
inputCopy
13 4 1 3
3 2 6 4 1 4 4 7 1 3 3 2 4
4 3 4
outputCopy
9
1 2 3 4 5 9 11 12 13
Note
In the first example, if you don’t remove any flowers, the machine would put out two workpieces with flower types [1,2,3] and [3,2,1]. Those workpieces don’t fit Diana’s schematic. But if you remove flower on 4-th place, the machine would output workpieces [1,2,3] and [2,1,2]. The second workpiece fits Diana’s schematic.

In the second example there is no way to remove flowers so that every citizen gets a wreath and Diana gets a workpiece that fits here schematic.

In the third example Diana is the only citizen of the town and that means she can, for example, just remove all flowers except the ones she needs.

题意:

给你m个花,有n个人,每个人都要一个花环,k朵花能造一个花环,造花环的时候是把最前面的k朵拿来,你要拿走一些花,使得剩下的花所做的花环能让每个人都有,并且其中某个花环需要包括下面s个花,其他随意。

题解:

很明显的尺取,跳出循环的条件就是后面的指针指到了末尾,或者当前取的区间满足条件。首先我们移动尾指针,使得首指针与尾指针之间至少有k朵花,并且这个区间包含必要的s朵花,由于它是每次去最前面的k朵,所以要让这个范围内的被取到,首指针前面的花的数量减去拿走的数量要是k的倍数,在首尾指针内部也要取走p2-p1+1-k数量的花来满足答案,很明显我们能拿走m-n*k朵花,如果前面这两项加起来小于这个值,那首指针就要向后移,同时如果首尾指针其中的花不满足条件s,那么就跳出首指针后移的循环,如果移动后满足条件s,那么就跳出循环。最后检查一遍看看那些需要去掉

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int need[N],a[N],num[N];
int main()
{
    int m,k,n,s;
    scanf("%d%d%d%d",&m,&k,&n,&s);
    for(int i=1;i<=m;i++)
        scanf("%d",&a[i]);
    int x;
    for(int i=1;i<=s;i++)
        scanf("%d",&x),need[x]++;
    int cnt=0;
    int p1=1,p2=0,flag=0;
    while(p2<m)
    {
        while(p2-p1+1<k||cnt<s)
        {
            num[a[++p2]]++;
            if(num[a[p2]]<=need[a[p2]])
                cnt++;
            if(p2>=m)
                break;
        }
        while(p1<=p2&&(p1-1)%k+(p2-p1+1)-k>m-k*n)
        {
            num[a[p1++]]--;
            if(num[a[p1-1]]<need[a[p1-1]])
            {
                cnt--;
                break;
            }
        }
        if(cnt==s)
        {
            flag=1;
            break;
        }
    }
    if(!flag)
        return 0*printf("-1\n");
    int res=m-n*k-(p2-p1+1-k);
    printf("%d\n",m-n*k);
    for(int i=(n-1)*k+1;i<p1;i++)
        printf("%d ",i),res--;
    int del=0;
    for(int j=p1;j<=p2;j++)
    {
        if(p2-p1+1-del<=k)
            break;
        if(need[a[j]]<num[a[j]])
            printf("%d ",j),num[a[j]]--,del++;
    }
    for(int i=p2+1;i<=m;i++)
        if(res)
            printf("%d ",i),res--;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/88768022
今日推荐