LOJ #2156. 「POI2011 R1」棒棒糖 Lollipop(构造)

题目

我们把价格为 2 2 看做是长度为 2 2 ,构成一个新的有很多个分界点为原来棒棒糖中不同口味的分界点的棒棒糖。
考虑暴力,我们是从左往右扫,如果相距为 k k 的两个点都是分界点,那么这就是一组答案。
考虑如果
1.当前两个点都不是分界点,那么右移长度1就一定两个都是。
2.如果有一个不是,
、那么如果是分界点那一个点后面是长度为1的口味,
、那么右移长度1也可以合法,
、否则:
、、右移长度1,重复2处的判断。

我们发现上面这个算法可以优化为:
如果坐标为 k k 的点事分界点,那么答案就是 [ 0 , k ] [0,k]
否则,分别找到 0 0 k k 后面第一个长度为 1 1 的段,求个合法方案即可。

A C   C o d e \mathrm {AC \ Code}

#include<bits/stdc++.h>
#define maxn 2000005
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
#define per(i,j,k) for(int i=(j);i>=(k);i--)
using namespace std;

int n,m,L,a[maxn],r[maxn];
char s[maxn];

int main(){
	scanf("%d%d",&n,&m);
	scanf("%s",s);
	rep(i,0,n-1){
		int t=L;
		L+=(s[i]=='T')+1;
		rep(j,t,L-1) a[j]=i;
 	}
 	int p=L+1;
 	per(i,L-1,0){
 		if(s[a[i]] == 'W') p=i;
 		r[i]=p;
	}
	for(int k;m--;){
		scanf("%d",&k);
		if(k>L) puts("NIE");
		else if(a[k]^a[k-1])	printf("%d %d\n",1,a[k-1]+1);
		else{
			int t=min(r[0]+1+k,r[k]+1);
			if(t > L) puts("NIE");
			else printf("%d %d\n",a[t-k]+1,a[t-1]+1);
		}
	}
}

发布了627 篇原创文章 · 获赞 91 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/103705002
今日推荐