- 注册时间
- 2007-12-28
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 12785
- 在线时间
- 小时
|
发表于 2009-3-12 23:23:27
|
显示全部楼层
哈哈,代码终于完成了。程序中用到了一条汇编指令。在PIV 2.6G,5000个数据,用时大约0.3秒。
楼主可用我的代码跑一下,看看能你目前的版本快多少。
下面给出程序。- #include <stdlib.h>
- #include <stdio.h>
-
- #include <windows.h> //for GetTickCount function declare
-
- typedef unsigned __int64 UINT64;
- typedef unsigned long DWORD;
- typedef unsigned char BYTE;
-
- /*
- This topic can be found at
- http://acm.timus.ru/problem.aspx?space=1&num=1318
- */
-
- typedef struct
- {
- DWORD U[4];
- }UINT128;
-
-
- UINT128 pow10[40];
- UINT128 tabLimit[128];
- BYTE tabValue[128];
-
- void set( UINT128 *n1,DWORD n)
- {
- n1->U[0]=0;
- n1->U[1]=0;
- n1->U[2]=0;
- n1->U[3]=n;
- }
-
- //if n1>=n2 return 1 ,else return 0;
- int ge( UINT128 *n1, UINT128 *n2)
- {
- if ( n1->U[0] > n2->U[0] )
- return 1;
- else if ( n1->U[0] < n2->U[0] )
- return 0;
-
- if ( n1->U[1] > n2->U[1] )
- return 1;
- else if ( n1->U[1] < n2->U[1] )
- return 0;
-
- if ( n1->U[2] > n2->U[2] )
- return 1;
- else if ( n1->U[2] < n2->U[2] )
- return 0;
-
- if ( n1->U[3] >= n2->U[3] )
- return 1;
- else
- return 0;
- }
-
- inline int _log2(DWORD r)
- {
- _asm
- {
- bsr eax,r
- }
- }
-
- int log2( UINT128 *n1)
- {
- int i=0;
- while ( n1->U[i]==0 && i<=3)
- i++;
- if (i==4)
- return 0;
-
- return (3-i)*32+_log2(n1->U[i]);
- }
-
- void Mul( UINT128 *n,DWORD m)
- {
- int i;
- UINT64 x=0;
- for (i=3;i>=0;i--)
- {
- x+= (UINT64)(n->U[i]) * (UINT64)m;
- n->U[i]=(DWORD)(x);
- x >>= 32;
- }
- }
-
- void InitSearchTab()
- {
- int i,j,shift,base;
- UINT128 r,low;
-
- set(&r,1);
- for (i=0;i<=38;i++)
- {
- pow10[i]=r;
- Mul(&r,10);
- }
-
- tabValue[0]=0;
- set( &(tabLimit[0]),10);
- base=0;
- for (i=1;i<127;i++)
- {
- shift= i % 32;
- low.U[0]=low.U[1]=low.U[2]=low.U[3]=0;
- low.U[3-i/32]= 1L << shift;
-
- if (base<38 && ge( &low,&(pow10[base+1]) ) )
- base++;
-
- j=base;
- while ( ge( &low,&(pow10[j]) ) && j<=38 )
- j++;
-
- tabLimit[i]=pow10[j];
- tabValue[i]=j-1;
- }
- }
-
- int logSum( UINT128 *data,int count)
- {
- int i,j,bc;
- UINT128 t;
- DWORD r=0;
-
- for (i=0;i<count;i++)
- {
- for (j=i+1;j<count;j++)
- {
- t=data[i];
-
- t.U[0] ^= data[j].U[0];
- t.U[1] ^= data[j].U[1];
- t.U[2] ^= data[j].U[2];
- t.U[3] ^= data[j].U[3];
-
- bc= log2(&t);
- if (bc==127)
- r+=38;
- else
- r+= tabValue[bc];
- if ( ge( &t, &(tabLimit[bc])) )
- r++;
- }
- }
-
- return r*2;
- }
-
- int main(int argc, char* argv[])
- {
- int i,count;
- DWORD d0,d1,d2,d3, nlogSum;
- UINT128 *pData=NULL;
- DWORD t=GetTickCount();
-
- InitSearchTab();
- scanf("%d",&count);
-
- pData=new UINT128[count];
-
- for (i=0;i<count;i++)
- {
- scanf("%u %u %u %u",&d0,&d1,&d2,&d3);
- pData[i].U[0]=d0;
- pData[i].U[1]=d1;
- pData[i].U[2]=d2;
- pData[i].U[3]=d3;
- }
-
- nlogSum= logSum(pData,count);
- delete[] pData; pData=NULL;
-
- printf("%u\n",nlogSum);
- t=GetTickCount()-t;
- printf("It take %d ms\n",t);
-
- return 0;
- }
复制代码 |
评分
-
查看全部评分
|