• 多校 2009 3


    D n 然后n个数  (1<=数<=n)  要求是变成序列1-n  按顺序  可以交换相邻2个数字a  b  花费是 a+b 求最小花费

    线段数维护  区间里的数的数目  然后区间的和  每个数 查询比他小的数目的个数和 他们的和 那么花费就是  数目 *a + sum   long long

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<iostream>
    
    using namespace std;
    
    #define MAXN 100010
    #define inf  1000000007
    #define ll long long
    struct node
    {
        int l,r,w;
        ll sum;
    }tree[MAXN<<2];
    void Build(int l,int r,int a)
    {
        tree[a].l=l;
        tree[a].r=r;
        tree[a].w=0;
        tree[a].sum=0;
        if(l==r)
            return ;
    
        int mid=(l+r)>>1;
        Build(l,mid,a<<1);
        Build(mid+1,r,a<<1|1);
    }
    int num;
    ll Ques(int l,int r,int a1,int b1,int a)
    {
        if(a1<=l&&r<=b1)
        {
            num=num+tree[a].w;
            return tree[a].sum;
        }
        int mid=(l+r)>>1;
        ll ans=0;
        if(a1<=mid)
            ans=ans+Ques(l,mid,a1,b1,a<<1);
        if(b1>mid)
            ans=ans+Ques(mid+1,r,a1,b1,a<<1|1);
        return ans;
    }
    ll z[MAXN];
    int ind[MAXN];
    void Update(int l,int r,int a1,int a)
    {
        if(l==r)
        {
            tree[a].w=1;
            tree[a].sum=l;
            return ;
        }
        int mid=(l+r)>>1;
        if(a1<=mid)
            Update(l,mid,a1,a<<1);
        else
            Update(mid+1,r,a1,a<<1|1);
        tree[a].w=tree[a<<1].w+tree[a<<1|1].w;
        tree[a].sum=tree[a<<1].sum+tree[a<<1|1].sum;
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            Build(1,n,1);
            for(int i=1;i<=n;i++)
                scanf("%lld",&z[i]);
    
            ll ans=0;
            for(int i=n;i>=1;i--)
            {
                num=0;
                ll sum=Ques(1,n,1,z[i],1);
                ans=ans+sum+num*z[i];//+num*z[i];
                //printf("%d
    ",ans);
                Update(1,n,z[i],1);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    H

    f(n)=f(n-1)+2*f(n-2)+1

    f(1)=1

    f(2)=2

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<iostream>
    
    using namespace std;
    
    #define MAXN 100010
    #define inf  1000000007
    #define ll long long
    
    struct node
    {
        ll z[3][3];
    }a,b;
    
    node mou(node a,node b,int c)
    {
        node ans;
        memset(ans.z,0,sizeof(ans.z));
        for(int i=0;i<3;i++)
        {
            for(int j=0;j<3;j++)
            {
                ll sum=0;
                for(int k=0;k<3;k++)
                    sum=sum+(a.z[i][k]*b.z[k][j])%c;
                ans.z[i][j]=sum;
            }
        }
        return ans;
    }
    node Quick(node a,int b,int c)
    {
        node ans;
        memset(ans.z,0,sizeof(ans.z));
        for(int i=0;i<3;i++)
            ans.z[i][i]=1;
        while(b>0)
        {
            if(b&1)
                ans=mou(ans,a,c);
            b>>=1;
            a=mou(a,a,c);
        }
        return ans;
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF&&n)
        {
            if(n==1)
                printf("1
    ");
            else if(n==2)
                printf("2
    ");
            else
            {
                 memset(a.z,0,sizeof(a.z));
                 a.z[0][1]=2;
                 a.z[1][0]=a.z[1][1]=a.z[2][1]=a.z[2][2]=1;
                 b=Quick(a,n-2,200907);
                 printf("%d
    ",(b.z[0][1]+2*b.z[1][1]+b.z[2][1])%200907);
            }
        }
        return 0;
    }
    View Code

     C

    f(n)=(n%10)^f(n/10)   f(0)=1  

    欧拉降幂 A^B%C=A^(B%ph(C)+ph(C)) %C     条件B>=ph(C)

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    
    using namespace std;
    
    #define MAXN 100010
    #define inf  1000000007
    #define ll long long
    
    ll ph(ll a)
    {
        ll b=a,c=a,en;
        en=sqrt(a);
        for(ll i=2;i<=en;i++)
        {
            if(c%i==0)
            {
                b=b/i*(i-1);
                while(c%i==0)
                    c=c/i;
            }
        }
        if(c>1)
            b=b/c*(c-1);
        return b;
    }
    ll Quick(ll a,ll b,ll c)
    {
        ll ans=1;
        while(b>0)
        {
            if(b&1)
                ans=(ans*a)%c;
            b>>=1;
            a=(a*a)%c;
        }
        return ans;
    }
    ll calc(ll a,ll b,ll mod)
    {
        ll ans=1;
        for(ll i=1;i<=b;i++)
        {
            ans=ans*a;
            if(ans>=mod)
                return ans;
        }
        return ans;
    }
    ll f(ll n,ll m)
    {
        if(n<10)
            return n;
        ll b=f(n/10,ph(m));//
        ll c=calc(n%10,b,m);
        if(c>=m)
        {
            ll ans=Quick(n%10,b,m);
            if(ans==0)
                ans=ans+m;
            return ans;
        }
        return c;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            ll n,m;
            scanf("%lld%lld",&n,&m);
            printf("%lld
    ",f(n,m));
        }
        return 0;
    }
    View Code

    A  页面置换算法 最佳置换算法 大概就是 最久不会使用到的被丢到

    先声明一下 我下面的代码是WA的   但是我觉得我是对的 我维护了第i个数字的下次使用的下标然后放到优先队列里维护 不知到为什么错

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    #include<queue>
    
    using namespace std;
    
    #define MAXN 100010
    #define inf  1000000007
    #define ll long long
    
    int z[MAXN];
    int nex[MAXN];
    bool vis[MAXN];
    int ind[MAXN];
    struct node
    {
        int w,w1;
        friend bool operator < (node a,node b)
        {
            return a.w>b.w;
        }
    };
    priority_queue<node>q1;
    
    int main()
    {
        int c,a,b;
        while(scanf("%d%d%d",&c,&a,&b)!=EOF)
        {
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=b;i++)
                scanf("%d",&z[i]);
            for(int i=0;i<=b;i++)
                ind[i]=inf;
            int ans=0;
            for(int i=b;i>=1;i--)
            {
                nex[i]=ind[z[i]];
                ind[z[i]]=i;
            }
            while(!q1.empty())
                q1.pop();
    
            for(int i=1;i<=b;i++)
            {
                int d=z[i];
                if(vis[d])
                    ;
                else
                {
                    if(q1.size()>=c)
                    {
                        node n1=q1.top();
                        q1.pop();
                        vis[n1.w1]=0;
                        node n;
                        n.w=nex[i]-i;
                        n.w1=z[i];
                        q1.push(n);
                        vis[d]=1;
                        ans++;
                    }
                    else
                    {
                        node n;
                        n.w=nex[i]-i;
                        n.w1=z[i];
                        q1.push(n);
                        vis[d]=1;
                        ans++;
                    }
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    G

    裸的莫比乌斯反演

    #include<stdio.h>
    
    #define MAXN 100000
    bool    mark[100005];
    int     prim[100005];
    int     mobi[100005];
    
    long long min(long long a,long long b)
    {
        return  a<b?a:b;
    }
    
    int main()
    {
        int T,i,j,k;
        mobi[1]=1;
        j=0;
        for(i=2;i<=MAXN;i++)
        {
            if(mark[i]==false)
            {
                prim[j++]=i;
                mobi[i]=-1;
            }
    
            for(k=0;k<j;k++)
            {
                if(i*prim[k]>MAXN)
                    break;
    
                mark[i*prim[k]]=true;
                if(i%prim[k]==0)
                {
                    mobi[i*prim[k]]=0;
                    break;
                }
                else
                    mobi[i*prim[k]]=-mobi[i];
            }
        }
    
        scanf("%d",&T);
    
        j=1;
    
        while(T--)
        {
            long long a,b,c,d;
            long long sum,sum2;
    
    
            scanf("%lld%lld",&b,&d);
            a=c=k=1;
            sum=0;
            sum2=0;
            a=b/k;
            c=d/k;
    
            for(i=1;i<=min(a,c);i++)
                sum=sum+mobi[i]*(a/i)*(c/i);
            for(i=1;i<=min(a,c);i++)
                sum2=sum2+mobi[i]*(min(a,c)/i)*(min(a,c)/i);
    
            printf("%lld
    ",sum);
        }
    
        return 0;
    }
    View Code

    J 多重背包   2进制优化 以前写过 就不写了

  • 相关阅读:
    使用RequireJS优化Web应用前端
    基线样式
    css层叠顺序
    摘录android工具类
    android中相关的图形类
    Google Android SDK开发范例------------20141119
    将博客搬至CSDN
    LightOJ1356 最大独立集 HK算法 素数分解
    求二分图最大匹配——Hopcroft-Krap算法
    HDU 6333 莫队分块 + 逆元打表求组合数
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6887965.html
Copyright © 2020-2023  润新知