[CSP-S Simulation Test]: Emotional Flutter (greedy)

Portal Title (title 51 inside)


Input Format

The first row represents an integer $ t $ the number of data sets.
The first line of each of the three data integer $ s, k, n $.
The second row has n-$ $ integer $ A_1, A_2, ..., A_n $, sequentially represents the length of black and white strips.


Output Format

If output by $ "TAK" $, or output $ "NIE" $.


Sample

Sample input:

2
2 8 7
2 5 6 3 2 1 2
2 8 4
1 6 7 4

Sample output:

YES
NO


Data range and tips

Sample explained:

data range:

$ 30 \% $ data, $ n-\ leqslant 1300 $;
$ 50 \% $ data, $ n \ leqslant 22,000 $;
data $ 100 \% $ a, $ 2 \ leqslant n \ leqslant 500,000,1 \ leqslant s <k \ leqslant {10} ^ 9,1 \ leqslant A_i \ leqslant {10} ^ 9,1 \ leqslant t \ leqslant 10 $.
Graded data. Please use the large input files to optimize read.


answer

Is actually a greedy, the main strategy is difficult to think.

First, let's deal with the length of the foot, we can put all the black blocks to extend $ s $, all the white blocks to move the left point to the right $ s $, so pretty and overlooked the length of the foot.

Then there will be some special cases the sentence, for my greedy strategy, we only need to use when a black block when a length greater than $ k $, certainly jump over, so the direct output $ "NIE" $ can.

For the general case now in terms of how I judge.

First, all the points left and right points of the black block are $ \ mod k $, then we can not be off during this interval; if there is $ \ $ finished after mod k right point less than the left point, then the interval $ [0, r] $ interval and $ [l, k-1] $ not jump.

After all we only need to not jump interval row a sequence, then we just need to find a take-off point can be.

Details more slowly adjust it ......

Time complexity: $ \ Theta (n \ log n) $.

Expectations score: $ 100 $ points.

Actual score: $ 100 $ points.


Code time

#include<bits/stdc++.h>
using namespace std;
struct rec{long long l,r;}e[10000000];
long long s,k,n;
long long sum[5000001];
long long lft[5000001],rht[5000001],wsq;
int top;
bool flag;
bool cmp(rec a,rec b){return a.l==b.l?a.r<b.r:a.l<b.l;}
int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		scanf("%lld%lld%lld",&s,&k,&n);
		top=flag=wsq=0;
		for(int i=1;i<=n;i++)
		{
			long long a;
			scanf("%lld",&a);
			if(i&1)a+=s;
			else{a-=s;a%=k;}
			if(a>k)flag=1;
			sum[i]=sum[i-1]+a;
			if(i&1)
			{
				lft[i]=sum[i-1]+1;
				rht[i]=sum[i]-1;
			}
		}
		if(((n&1)&&sum[n]<=k)||((!(n&1))&&sum[n-1]<=k)){puts("TAK");continue;}
		if(flag){puts("NIE");continue;}
		for(int i=1;i<=n;i+=2)
		{
			lft[0]=lft[i]%k;
			rht[0]=rht[i]%k;
			if(rht[0]<lft[0])
			{
				e[++top]=(rec){0,rht[0]};
				e[++top]=(rec){lft[0],k-1};
			}
			else e[++top]=(rec){lft[0],rht[0]};
		}
		sort(e+1,e+top+1,cmp);
		if(e[1].l){puts("TAK");goto nxt;}
		for(int i=1;i<=top;i++)
		{
			if(wsq+1<e[i].l){puts("TAK");goto nxt;}
			wsq=max(wsq,e[i].r);
		}
		if(wsq<k-1){puts("TAK");continue;}
		puts("NIE");
		nxt:;
	}
	return 0;
}

rp++

Guess you like

Origin www.cnblogs.com/wzc521/p/11569467.html