bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换*&&bzoj1692[Usaco2007 Dec]队列变换*

Posted YuanZiming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换*&&bzoj1692[Usaco2007 Dec]队列变换*相关的知识,希望对你有一定的参考价值。

bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换

bzoj1692[Usaco2007 Dec]队列变换

题意:

有一个奶牛队列。每次可以在原来队列的首端或是尾端牵出一头奶牛,把她安排到新队列的尾部,然后对剩余的奶牛队列重复以上的操作,直到所有奶牛都被插到了新的队列里。这样得到的队列,就是FJ拉去登记的最终的奶牛队列。 求对于给定的奶牛们的初始位置,计算出可能得到的字典序最小的队列。队列大小≤30000。

题解:

有一个结论:如果当前队列中的队首元素不等于队尾元素,则选小的那一边;否则选以右端点为下标的前缀和以左端点为下标的后缀中较小的那边。对于比较前缀后缀,正解是后缀数组,然而本弱偷懒写了个哈希,比较两个字符串的大小只要二分LCP,然后比较LCP的下一个字符即可。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 30010
 7 #define ll unsigned long long
 8 #define num 233
 9 using namespace std;
10 
11 inline int read(){
12     char ch=getchar(); int f=1,x=0;
13     while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
14     while(ch>=0&&ch<=9)x=x*10+ch-0,ch=getchar();
15     return f*x;
16 }
17 ll hash1[maxn],hash2[maxn],mi[maxn]; int l,r,n,tot; char name1[maxn],name2[maxn],ans[maxn];
18 bool cmp(int x,int y){
19     int l=1,r=min(n-x+1,y),z=0;
20     while(l<=r){
21         int mid=(l+r)>>1;
22         if(hash1[x+mid-1]-hash1[x-1]*mi[mid]==hash2[n-y+1+mid-1]-hash2[(n-y+1)-1]*mi[mid])z=mid,l=mid+1;else r=mid-1;
23     }
24     return name1[x+z]<=name2[n-y+1+z];
25 }
26 int main(){
27     n=read(); inc(i,1,n)scanf("%s",name1+i); inc(i,1,n)name2[i]=name1[n-i+1]; mi[0]=1;
28     inc(i,1,n)hash1[i]=hash1[i-1]*num+name1[i],hash2[i]=hash2[i-1]*num+name2[i],mi[i]=mi[i-1]*num;
29     l=1; r=n;
30     while(l<r){
31         if(name1[l]<name1[r])ans[++tot]=name1[l],l++;
32         else if(name1[l]>name1[r])ans[++tot]=name1[r],r--;
33         else if(cmp(l,r))ans[++tot]=name1[l],l++;
34         else ans[++tot]=name1[r],r--;
35     }
36     ans[++tot]=name1[l]; inc(i,1,tot){printf("%c",ans[i]); if(i%80==0)puts("");} return 0;
37 }

 

20161102

以上是关于bzoj1640[Usaco2007 Nov]Best Cow Line 队列变换*&&bzoj1692[Usaco2007 Dec]队列变换*的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1640 [Usaco2007 Nov]Best Cow Line 队列变换:贪心字典序最小

1640: [Usaco2007 Nov]Best Cow Line 队列变换|后缀数组|贪心

[BZOJ] 1706: [usaco2007 Nov]relays 奶牛接力跑

BZOJ 1707 [Usaco2007 Nov]tanning分配防晒霜

[BZOJ1706][usaco2007 Nov]relays 奶牛接力跑

[BZOJ1642][Usaco2007 Nov]Milking Time 挤奶时间