#
hash.同余.不过这里的同余不是普通意义上的同余.
#include <iostream>
#include <fstream>
using namespace std;
//ifstream fin("1.txt");
const int MAXN=100001;
const int mod=99991;
int n,k;
int c[MAXN][30];
int d[MAXN][30];
int h[mod];
int p[MAXN],len=0;
int s[MAXN];
int result=0;
inline int hashcode(const int id)

{
int s = 0;
for(int i=0; i<k; i++)
s=((s<<2)+(d[id][i]>>4))^(d[id][i]<<10);
s = s % mod;
s = s < 0 ? s + mod : s;
return s;
}


void find_hash(int x,int id)


{
int f[30];
bool ok=true;
for (int i=0;i<k;i++)

{
if (i==0) f[i]=c[id][i]-c[p[x]][i];
else

{
f[i]=c[id][i]-c[p[x]][i];

if (f[i]!=f[i-1]||f[i]==0)
{ok=false;break;}
}
}
if (ok)

{
if (result<id-p[x])

{
result=id-p[x];
}
}
if (s[x]==-1)

{
len++;
s[x]=len;
s[len]=-1;
p[len]=id;
return;
}
else

{
find_hash(s[x],id);
}
}
void hash(int u,int id)


{
if (h[u]==-1)

{
len++;
h[u]=len;
s[len]=-1;
p[len]=id;
return;
}
find_hash(h[u],id);
}
int main()


{
cin>>n>>k;

if (n==1)
{cout<<1<<endl;exit(0);}
memset(h,-1,sizeof(h));
memset(c,0,sizeof(c));
for (int i=1;i<=n;i++)

{
int x;
cin>>x;
int l=-1;
for (int j=0;j<k;j++)

{
int p=x%2;
l++;
c[i][l]=c[i-1][l]+p;
x/=2;
}
}
memcpy(d,c,sizeof(c));
for (int i=0;i<=n;i++)

{
int max=MAXN;
for (int j=0;j<k;j++)

{
if (max>d[i][j]) max=d[i][j];
}
for (int j=0;j<k;j++)

{
d[i][j]-=max;
}
int u=hashcode(i);
//cout<<u<<endl;
hash(u,i);
}
cout<<result<<endl;
// system("pause");
return 0;
}

这题做的很搞笑..
真得总结总结..
把方程分成两半,然后计算其中一半,存入hash.
如果枚举另一半,然后与hash表对照..并累加..
可笑的我一开始用了两个大数组来当hash..直接1对1映射累加..然后内存超了..
然后后来才想起来..只用一个hash..然后另一个来找就行了..
但是我用的大数组还是大了..
应该写一个hash才好..
于是怒了..直接map扔上去..- -
#include <iostream>
#include <map>
using namespace std;

long long result=0;
map<int,int> m;
int main()


{
int a1,a2,a3,a4,a5;
cin>>a1>>a2>>a3>>a4>>a5;

for (int i=-50;i<=50;i++)
for (int j=-50;j<=50;j++)

{
if (i==0||j==0) continue;
int x=i*i*i*a4+j*j*j*a5;
map<int,int>::iterator iter=m.find(x);
if (iter==m.end())

{
m.insert(make_pair(x,1));
}
else

{
iter->second++;
}
}

for (int i=-50;i<=50;i++)
for (int j=-50;j<=50;j++)
for (int k=-50;k<=50;k++)

{
if (i==0||j==0||k==0) continue;
int x=i*i*i*a1+j*j*j*a2+k*k*k*a3;
map<int,int>::iterator iter=m.find(-x);
if (iter!=m.end())

{
result+=iter->second;
}
}
cout<<result<<endl;
system("pause");
return 0;
}

算上有道..第三次玩tc..
不知道是div1...看第一题挺简单的..就得意忘形了...也没有仔细看看..想当然了..最后终于被cha了..
不过有幸在room里发现了Petr..怎是orz啊..
大牛就是大牛..报了名..没参加比赛..
哎.血一般的教训..下回努力
预赛66....orz..只能说是个很吉利的数字...
长期放置java..这个成绩还在接受范围呢..
进复赛应该没问题吧...
话说当初我就说了..这样的题60分就应该能进..除非专门天天去背来背去..
现在果然灵验了..
好了..吃点东西去..下午还有ural..晚上还有topcoder..forza
ural做了2个半小时..
做的很糟..只切了2道题...
除了能力,另一个就是英语问题..
根据提交来看..应该有4-5道水题...
题目大致能看懂...但几个细节一直看不懂..
于是一个wa on 5..一个wa on 3...orz啊..orz..
B. Sandro's Book..
这题最水..枚举字符串就完了..
不过我wa了一次..因为有个细节没看懂...- -我都快怀疑我在猜题目了..
J. Dill..
最最最最最简单的构造..对于第一组箱子..可以把1-n给第一组..
那么第二组的m个可以构造成n+1,n+1+n,n+1+2*n.....
因为代码都很短..就不帖了..囧