比赛结束这么多天了才去看比赛中的一些题,突然就觉得应该反问一下自己这些天都在做些什么了!!!似乎一直在纠结与2-sat,老是建不对图,老是各种错,然后就将比赛中的题一拖再拖。今天同学来了,在这郑州的大夏天,38度的高温实在不知道该把他带到哪里,后来想想把他带机房了,然后他在玩电脑,我刷了这道题,突然小有成就感,感觉时间也没有纯粹浪费掉的!
以前没求过哈弗曼顿距离,还是看了网上的求哈弗曼顿最远距离的算法,感觉又学到了一个知识,好高兴啊,每天学习一点点,然后进步也是很客观的吗!!!!
推荐一篇博客,感觉说的挺清晰的,一看就懂了:http://hi.baidu.com/lin791263068/item/224a90a69d8973298919d3b3
下面是我的代码,因为自己位运算没有弄好,还wa了几次,无语啦!不过思路还是对的!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<climits>
#include<cmath>
#include<cstdlib>
#include<set>
using namespace std;
#define rep(i,n) for(int i=0; i<(n); ++i)
#define repf(i,a,b) for(int i=(a), i<=(b); ++i)
#define repd(i,a,b) for(int i=(a); i>=(b); ++i)
#define N 100010
#define M 6
int a[N][M];
int n,m;
multiset<int>q[1<<M];
multiset<int>::iterator it1,it2;
int ans()
{
int sum=0;
rep(i,1<<m)
{
it1=q[i].begin();
it2=q[i].end();
if(it1==it2) break;//为空的
--it2;
sum=max(sum,abs(*it1-*it2));
}
return sum;
}
int main()
{
int sign,x,y;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(a,0,sizeof(a));
rep(i,1<<m)
q[i].clear();
rep(i,n)
{
scanf("%d",&sign);
if(sign==0)
{
rep(j,m) scanf("%d",&a[i][j]);
rep(j,1<<m)
{
int sum=0;
rep(k,m)
{
if(((j>>k)&1)==1)
sum+=a[i][k];
else sum-=a[i][k];
}
q[j].insert(sum);
}
}
else
{
scanf("%d",&x);
--x;
rep(j,1<<m)
{
int sum=0;
rep(k,m)
if(((j>>k)&1)==1) sum+=a[x][k];
else sum-=a[x][k];
// cout<<sum<<endl;
q[j].erase(q[j].find(sum));
}
}
printf("%d\n",ans());
}
}
return 0;
}