洛谷 分治算法

快速幂模板***

#include 
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 
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
using namespace std;
typedef long long ll;

ll Merge_and_Count(vector &a,vector &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 &a,vector &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 &a,int n)
{
    vectortmpA(a.begin(),a.end());
    ll ans=Merge_Sort_and_Count(a,tmpA,0,n-1);
    return ans;
}
int main()
{
    int n;cin>>n;
    vectora(n,0);
    for(int i=0;i>a[i];
    cout<

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

#include
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=0;i--)//从下往上输出
    {
        for(int j=0;j

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

你可能感兴趣的:(ACM)