洛谷 分治算法

快速幂模板***

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll quick_pow(ll n,ll k,ll MOD)
{
    ll ans=1,base=n;
    while(k>0)
    {
        if(k&1) ans=ans*base%MOD;
        base=base*base%MOD;
        k>>=1;
    }
    return ans%MOD;
}
int main()
{
    ll n,k,MOD;
    scanf("%lld%lld%lld",&n,&k,&MOD);
    printf("%lld^%lld mod %lld=%lld",n,k,MOD,quick_pow(n,k,MOD));
}

幂次方*****
将n用2的幂次方表示,输出只包括0,1
分析:n<20000,所有快速幂打表只到2^15,解决方法就是循环调用我们的输出函数

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int quick_pow(int n,int k)
{
    int ans=1,base=n;
    while(k>0)
    {
        if(k&1) ans=ans*base;
        base=base*base;
        k>>=1;
    }
    return ans;
}
int a[16];
int f(int n)
{
   int k=15;
   while(a[k]>n)k--;
   return k;
}
void solve(int n)
{
    int sum=n;
    while(sum>0)
    {
        if(sum!=n)printf("+");
        int res=f(sum);//2的幂次
        printf("2");
        if(res==0)printf("(0)");
        else if(res>1)
        {
            printf("(");
            solve(res);
            printf(")");
        }
        sum-=a[res];
    }
}
int main()
{
    for(int k=0;k<=15;k++)
    {
        a[k]=quick_pow(2,k);
    }
    int n;
    cin>>n;
    solve(n);
}

**逆序对
利用归并排序,修改一下,求逆序对的个数
我使用递归的办法。(题目n<=50万)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll Merge_and_Count(vector<int> &a,vector<int> &tmpA,int L,int mid,int R)
{
    int i=L,j=mid+1;
    int tmpid=L;
    ll ans=0;
    while(i<=mid && j<=R)
    {
        if(a[i]<=a[j]) tmpA[tmpid++]=a[i++];
        else
        {
            tmpA[tmpid++]=a[j++];
            ans+= mid-i+1;
        }
    }
    while(i<=mid) tmpA[tmpid++]=a[i++];
    while(j<=R) tmpA[tmpid++]=a[j++];

    for(int i=L;i<=R;i++)
        a[i]=tmpA[i];
    return ans;
}
ll Merge_Sort_and_Count(vector<int> &a,vector<int> &tmpA,int L,int R)
{
    if(L>=R) return 0;
    int mid=(L+R)/2;
    ll ans1=Merge_Sort_and_Count(a,tmpA,L,mid);
    ll ans2=Merge_Sort_and_Count(a,tmpA,mid+1,R);
    ll ans3=Merge_and_Count(a,tmpA,L,mid,R);
    return ans1+ans2+ans3;
}
ll CountInversion(vector<int> &a,int n)
{
    vector<int>tmpA(a.begin(),a.end());
    ll ans=Merge_Sort_and_Count(a,tmpA,0,n-1);
    return ans;
}
int main()
{
    int n;cin>>n;
    vector<int>a(n,0);
    for(int i=0;i<n;i++) cin>>a[i];
    cout<<CountInversion(a,n);
}

南蛮图腾*
对于当前图案,进行向右向上复制n次,并输出
初始为 ; 但是怎么实现呢?向上复杂,那我们就向右向下,到时候从下面开始输出即可。
/\ 从下面开始输出的话,最小单元的初始图案都是倒着的,所有,我们再把图形也
/\ 倒一下,变成 /\这样。从下往上输出就没问题了。
/\

#include<iostream>
using namespace std;
char a[1024][2048];
int main()
{
    int n,length=4;//图腾的宽
    cin>>n;
    for(int i=0;i<1024;i++)
        for(int j=0;j<2048;j++)
            a[i][j]=' ';
    a[0][0]=a[1][1]='/',a[0][1]=a[0][2]='_',a[0][3]=a[1][2]='\\';//倒着保存图腾
    for(int k=1;k<n;k++)//复制
    {
        for(int i=0;i<length/2;i++)
            for(int j=0;j<length;j++)
                a[i+(length/2)][j+(length/2)]=a[i][j+length]=a[i][j];
        length*=2;
    }
    for(int i=(length/2)-1;i>=0;i--)//从下往上输出
    {
        for(int j=0;j<length;j++)
            cout<<a[i][j];
        cout<<endl;
    }
    return 0;
}

看题解,发现找规律还和杨辉三角有关系,(把图形中的空格抽象成0,其他是1,厉害了)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值