zoukankan      html  css  js  c++  java
  • 【BZOJ1702】[usaco2007margold]队列平衡

    原来蛤习线性探测的时候要每次加一个稍大一点的数而不是每次+1……连蛤习都不会写,我tmd是有多弱

    原题:

    N(1<=N<=100000)头牛,一共K(1<=K<=30)种特色,
    每头牛有多种特色,用二进制01表示它的特色ID。比如特色ID为13(1101),则它有第1、3、4种特色。
    所以,我们认为第i头牛有第J个特色,那么整数k的二进制的第j位 肯定是 1.

    [i,j]段被称为平衡当且仅当K种特色在[i,j]内拥有 次数相同。

    求能够平衡的最大的[i,j]段的长度。

    这题附近都是蛤习,所以就往蛤习方面想了

    然后想了一段时间无果,决定看题解,看了几个题解都没看懂,但是受到启发,最终脑补出正解

    首先每一位求一下前缀和,两组前缀和相减就可以求得一段区间内的个数,然后给相邻两个前缀和做差,如果有两组前缀和元素之间的差都相等,这两组前缀和做差就可以使中间的值相等

    恩可以这么理解,如果两组前缀和元素之间的差相等,那么一组前缀的每个元素到另一组前缀和的对应元素的delta是一样的(因为从一组到另一组相对差没变),这两组前缀和减一下,每个元素的差都相等(感觉有点差分的意思?)

    然后有一些细节需要注意

    首先需要设置一组全部为零的前缀和或前缀和的差,因为可能出现某一组前缀和里面所有元素都相等,这个时候就要和0减

    因为添加元素0进去了,这时候0就有意义了,hash的初值就不能设成0

    以及蛤习线性探测的时候要每次加一个稍大一点的数而不是每次+1

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int read(){int z=0,mark=1;  char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
     9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    10     return z*mark;
    11 }
    12 int n,m,s[110000][50];
    13 int difference[110000][50];
    14 int maxx=0;
    15 int hash[510000],ha_top=159787;
    16 bool check(int x,int y){
    17     for(int i=2;i<=m;i++)  if(difference[x][i]!=difference[y][i])  return false;
    18     return true;
    19 }
    20 int get_hash(int x){
    21     int z=0;
    22     for(int i=2;i<=m;i++)  z=(z+difference[x][i]*94406+5195)%ha_top;
    23     while(hash[z]!=-1 && !check(hash[z],x)){  z+=283;  if(z>ha_top)z%=ha_top;}
    24     if(hash[z]==-1){  hash[z]=x;  return x;}
    25     return hash[z];
    26 }
    27 void get_s(int x,int y){  for(int i=1;y;i++,y>>=1)  s[x][i]+=y&1;}
    28 int main(){//freopen("ddd.in","r",stdin);
    29     memset(s,0,sizeof(s));
    30     memset(difference,0,sizeof(difference));
    31     memset(hash,-1,sizeof(hash));
    32     cin>>n>>m;
    33     get_hash(0);
    34     for(int i=1;i<=n;i++){
    35         get_s(i,read());
    36         for(int j=1;j<=m;j++)  s[i][j]+=s[i-1][j],difference[i][j]=s[i][j]-s[i][j-1];
    37         maxx=max(maxx,i-get_hash(i));
    38     }
    39     /*for(int i=1;i<=n;i++){
    40         for(int j=1;j<=m;j++)  cout<<s[i][j]<<" ";
    41         cout<<endl;
    42     }
    43     cout<<endl;
    44     for(int i=1;i<=n;i++){
    45         for(int j=1;j<=m;j++)  cout<<difference[i][j]<<" ";
    46         cout<<endl;
    47     }*/
    48     cout<<maxx<<endl;
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    小程序配置 全局配置
    浅谈 Nginx和LVS的各种优缺点
    LVS负载均衡(LVS简介、三种工作模式、十种调度算法)
    用Camshift算法对指定目标进行跟踪
    AsyncTask源代码解析
    shell中的${},##和%%的使用
    hdu 1081 &amp; poj 1050 To The Max(最大和的子矩阵)
    POJ 1141 Brackets Sequence (区间DP)
    Ejb in action(六)——拦截器
    7.JAVA编程思想笔记隐藏实施过程
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6336540.html
Copyright © 2011-2022 走看看