getdis有点像Astar中的“估价函数”。计算(x,y)与当前点范围的差距有多少,然后按顺序遍历左二子和右儿子。这样,如果更新到最优值,就能及时退出。这种算法在随机数据上是lg的,但是在构造数据上约是sqrt的。
【BZOJ2716&2648】双倍经验。就是裸的K-D TREE模板套套。无压力1A~。
【BZOJ3053】哎,说多了都是泪。这道题调了不知道多少时间。首先,它拓展到了K维空间上。这样,cmp就只需判断某一位的大小就行了。然后要查询前m优值。因为m<=10,我为了效率,直接一遍做,开了一个数组记录最优值。然后判断最优值的时候裸O(n)(均摊)的更新答案。
对于那个估计函数也要稍稍改一下(因为是欧几里得距离),怎么方便怎么来!(反正只会影响到效率)
调了半天后,总算小数据对拍没有问题了~~浪交!T了。。。
后来我估计在更新答案时速度太慢,于是一咬牙,把10个最优解开成了队列......
然后大数据对拍~~什么,秒WA?这下真的调了一个下午(因为我是刚学的),后来发现:RZZ的博客里的nth过程用错了。比如从l到r,中间是mid(默认数组下标从1开始),应该是a+l,a+mid,a+r+1。最后一个+1因为是虚指针。但是前面都不用+1的(上面的代码已经修改过了)!!!!
最后又是RE。果断要数据!――发现只有一个测试点。我先写了个程序,把测试点拆成了好几个。然后一测:全过!和在一起:RE!原来,l和r要及时清零!!!呵呵,多么痛的领悟!
【截取程序】
var
ss:string;
cnt,n,m,a,i,j:longint;
begin
assign(input,'T.in');
reset(input);
while (not(eof)) do
begin
inc(cnt);
str(cnt,ss);
ss:='T'+ss+'.in';
assign(output,ss);
rewrite(output);
readln(n,m);
writeln(n,' ',m);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(a);
write(a,' ');
end;
writeln;
end;
readln(n);
writeln(n);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(a);
write(a,' ');
end;
writeln;
read(a);
writeln(a);
end;
close(output);
end;
end.
【对拍造数据】
#include
#include
#include
using namespace std; int main() { freopen("T.in","w",stdout); srand((int)time(0)); int n=50000,m=4,i,j; printf("%d %d\n",n,m); for (i=1;i<=n;i++) { for (j=1;j<=m;j++) printf("%d ",rand()%10000+1); printf("\n"); } int Q=1000; printf("%d\n",Q); while (Q--) { for (i=1;i<=m;i++) printf("%d ",rand()%10000+1); printf("%d\n",rand()%5+1); } return 0; }
【AC代码】
#include
#include
#include
#define N 50005 #define INF 21390627567143.0 using namespace std; const int orzSYC=1; struct arr { int d[5],max[15],min[15],l,r,id; arr() {l=0;r=0;id=0;} }a[N*4],aa[N]; struct pop { double x;int id; friend bool operator < (const pop &a,const pop &b){return a.x
ans; int n,m,Q,i,j,t,x[15],D,temp[21],root,opt,P,flag; inline int Read() { int x=0;char ch=getchar();bool positive=1; for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') positive=0; for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; return positive?x:-x; } inline int cmp(arr a,arr b) { return a.d[D]
>1); nth_element(aa+l,aa+mid,aa+r+1,cmp); for (int i=0;i
=a[k].d[deep]) swap(L,R); double now=sdis(k); if (L) ask(L,(deep+1)%m); int flag=0; if (ans.size()