首页 > 代码库 > bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列*

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列*

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

题意:

N头牛,一共K种特色。每头牛有多种特色。[i,j]段被称为balanced当且仅当K种特色在[i,j]内拥有次数相同。求最大的[i,j]段长度。n≤100000,k≤30。

题解:

得到式子:a[i][l]-a[j][l]=a[i][l-1]-a[j][l-1],l在2..k之间,移项得a[i][l]-a[i][l-1]=a[j][l]-a[j][l-1],l在2..k之间,故可以定义一个结构体,里面包含所有的a[i][l]-a[i][l-1],l在2..k之间,然后用set查找满足所有元素相等的最小j即可。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <set>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 100010
 7 using namespace std;
 8 
 9 inline int read(){
10     char ch=getchar(); int f=1,x=0;
11     while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
12     while(ch>=0&&ch<=9)x=x*10+ch-0,ch=getchar();
13     return f*x;
14 }
15 int sum[maxn][50],n,k,ans;
16 struct nd{
17     int id; int num[50];
18     bool operator < (const nd &a)const{inc(i,1,k-1)if(num[i]!=a.num[i])return num[i]<a.num[i]; return 0;}
19 };
20 multiset<nd>st; nd a;
21 int main(){
22     n=read(); k=read();
23     inc(i,1,n){
24         int x=read(); inc(j,1,k)sum[i][j]=sum[i-1][j]; for(int j=k-1;j>=0;j--)if(x&(1<<j))sum[i][j+1]++;
25     }
26     inc(j,1,k-1)a.num[j]=0; a.id=0; st.insert(a);
27     inc(i,1,n){
28         inc(j,1,k-1)a.num[j]=sum[i][j]-sum[i][j+1]; a.id=i;
29         multiset<nd>::iterator sti=st.find(a); if(sti==st.end())st.insert(a);else{
30             ans=max(ans,i-sti->id);
31         }
32     }
33     printf("%d",ans); return 0;
34 }

 

20160929

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列*