记录一些奇奇怪怪的骚操作

emm,想起来就更新

目录

1,读入挂

2,上下取整

3,防止掉精度

4,对于某些状态的压缩储存

5 矩形交的简便表示方法

6、线性求逆元

7、计算机算乘法比除法快

8、以十为底的快速幂


 

1,读入挂

据说读入挂可以在数据里 加一堆空格卡掉,但是我觉得没有哪个出题人闲的没事卡这个吧

int read(){
    int c = getchar(),Nig = 1,x = 0;
    while(!isdigit(c) && c != '-')
        c = getchar();
    if(c == '-')
        Nig = -1,c = getchar();
    while(isdigit(c))
        x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();
    return Nig*x;
}
#define read read()

2,上下取整

这个好理解

ceil(x/y)=\left\{\begin{matrix}k,(x = k*y,k=[0,1,2,3*****]) & & \\k+1,(x = [k*y+1,k*y+y-1],k=[0,1,2****]) & & \end{matrix}\right.

那么加一个y-1就好了(适用条件是x大于等于0,y大于0)

int ceil(int x,int y){
    return (x+y-1)/y;
}

也可以写成

int ceil(int x,int y){
    return (x-1)/y+1;
}

通用的上下取整,np函数是为了放置x*y超过long long

int np(ll x){
    return x>=0 ? (!x?0:1):-1;
}
ll floor(ll x,ll y){
    if(x%y == 0)
        return x/y;
    return (np(x)*np(y)>=0)?x/y:x/y-1;
}
ll ceil(ll x,ll y){
    if(x%y == 0)
        return x/y;
    return (np(x)*np(y)>=0)?x/y+1:x/y;
}

 

3,防止掉精度

1°强制转化的时候

1.0*比(double),1ll*比(long long)容易写多了

2°斜率

double也不一定保险,设k1=y1/x1,k2=y2/x2

k1=k2,就可以写成x1*y2==x2*y1

4,对于某些状态的压缩储存

例如

二维降维成一维,(这里推荐看一个例题、(虽然也可以不用,但是当时第一反应就是这个))

int mmp[n][m];
int tmp[n*m];
mmp[i][j] = tmp[i*m+j];

字符串hash,(例如,子串查找,Power Strings,Antisymmetry)

char s[] = "";
unsigned int k = 0,p = 1331;
///k是字符串hash成的那个数,p是一个素数,无符整数定义省去取模操作(大数取模费时间)
for(int i=0;s[i];i++)
    k = k*p + s[i];

有时候跑dfs的时候将状态(一个不大的矩阵)变成一个数用于去重,

int mmp[n][m],k = 0,p = 2;///k是最后的答案,p是mmp[i][j]的二进制最大位数
    for(int i=0;i

全排列那里有个康托展开

5 矩形交的简便表示方法

例题,Rectangles

 

6、线性求逆元

7、计算机算乘法比除法快

,所以某些情况下,写成除法的算法可以改成乘法以用来降低时间复杂度

例如

n的约数

一个dfs题,采用乘法比除法要快约十倍

#include
using namespace std;
typedef long long ll;
const int maxn = 50+7;
int prim[maxn]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
int t;
ll ans = 0,n;
void dfs(ll n,ll tans,int pos,int last){
    ans = max(ans,tans);
    if(pos<14)
    for(int i=0;n&&i<=last;i++,n/=prim[pos]){
        dfs(n,tans*(i+1),pos+1,i);
    }
}
int main(){
    for(scanf("%d",&t);t--;){
        scanf("%lld",&n);
        ans = 0;
        dfs(n,1,0,14);
        printf("%lld\n",ans);
    }
    return 0;
}

 

 

#include
using namespace std;
typedef long long ll;
const int maxn = 50+7;
int prim[maxn]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
int t;
ll ans = 0,n;
void dfs(ll num,ll tans,int pos,int last){
    ans = max(ans,tans);
    ll tmp = prim[pos];
    if(pos<14)
    for(int i=1;(num<=n/tmp)&&(i<=last);i++,tmp *= prim[pos])
        dfs(tmp*num,tans*(i+1),pos+1,i);
}
int main(){
    for(scanf("%d",&t);t--;){
        scanf("%lld",&n);
        ans = 0;
        dfs(1,1,0,14);
        printf("%lld\n",ans);
    }
    return 0;
}

 

8、以十为底的快速幂

众所周知,快速幂又叫慢速幂

这样可以加速、、(以下代码求的是2的n次方)

    ll ans = 1,A = 2;
    for(int i=n-1;~i;i--){
        ll num = s[i]-'0';
        ll t = Pow(A,num);//Pow是以二为底的快速幂
        ans = ans*t%mod;
        A = Pow(A,10ll);
    }

 

 

你可能感兴趣的:(杂谈(好吧,单纯就是个杂谈))