2018 hdu 多校 7

你们怎么什么都会?
我是真的菜,签到都失败了,还做了5个小时假题
1001 Age of Moyu
这道题是假的,原题之后放到别处
1005 GuGuFishtion
首先通过强行对a,b进行质因数分解,我们可以发现

G=gcd(a,b)ϕ(gcd(a,b)) G = g c d ( a , b ) ϕ ( g c d ( a , b ) )

我们设 a[i]=iϕ(i) a [ i ] = i ϕ ( i ) 然后式子就变成了
F(m,n)=i=1mj=1na[gcd(a,b)] F ( m , n ) = ∑ i = 1 m ∑ j = 1 n a [ g c d ( a , b ) ]

其实就是
F(m,n)=dmin(m,n)i=1mj=1na[d][gcd(a,b)=d] F ( m , n ) = ∑ d m i n ( m , n ) ∑ i = 1 m ∑ j = 1 n a [ d ] [ g c d ( a , b ) = d ]

这个式子就熟悉了,然后我们就大力反演,问题解决了。
因为ai不会比min(m,n)大,预处理到这个地方就可以了。

#include 
#define ll long long
#define endl '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);
    int ca ;
    cin>>ca;
    while(ca--)
    {
        ll a,b,c;
        ll aa,bb,cc;
        cin>>a>>b>>c;
        cin>>aa>>bb>>cc;
        ll num = a*bb - bb*c + b * cc - a * cc + aa*c - aa*b;
        ll den = a+b+c;
        if(num % den == 0)
        {
           cout<else
        {
           // cout<
            if( num < 0 ) 
{  
                cout << num/__gcd(-num,den) << "/" << den/__gcd(-num,den) << endl;
            } else
 {
                cout << num/__gcd(num,den) << "/" << den/__gcd(num,den) << endl;
            }
        }
    }
    return 0;
}

1010 Sequence
一看就是很简单的快速幂形式,加上学习莫比乌斯反演的时候学习了整除分块,我们就分块处理,每一块变更矩阵的参数就行。

#include 
#define ll long long
using namespace std;
const ll mod = 1e9 + 7;
struct Mat
{
    ll d[3][3];
    void init()
    {
        for(int i = 0; i<3; i++)
            for(int j = 0; j<3; j++)
                d[i][j]= 0;
    }
    void eye()
    {
        init();
        for(int i  =0; i<3; i++)
        {
            d[i][i] = 1;
        }
    }
    void show()
    {
        printf("\n");
        for(int i = 0; i<3; i++)
        {
            for(int j = 0; j<3; j++)
            {
                printf("%I64d ",d[i][j]);
            }
            puts("");
        }
    }

};
Mat operator * (Mat a,Mat b)
{
    Mat res;
    for(int i= 0; i<3; i++)
    {
        for(int j = 0; j<3; j++)
        {
            res.d[i][j] = 0;
            for(int k = 0; k<3; k++)
            {
                res.d[i][j] += (a.d[i][k] * b.d[k][j])%  mod;
            }
            res.d[i][j] %= mod;
        }
    }
    return res;
}
Mat pow_mod(Mat a,int n)
{
    Mat res;
    res.eye();
    while(n)
    {
        if(n & 1)
            res = res*a;
        a = a * a;
        n>>=1;
    }
    return res;
}
ll f[10];
ll getR(ll i,ll n,ll P)
{
    ll num = P / i;
    ll l = i,r = n;
    while(l < r)
    {
        ll mid = r - (r - l) / 2;
        if(P / mid == num)
        {
            l = mid;
        }
        else if(P / mid < num)
        {
            r = mid - 1;
        }
        else
        {
            l = mid + 1;
        }
    }
    return l;
}

int main()
{
    int ca;
    scanf("%d",&ca);
    while(ca--)
    {
        ll A,B,C,D,P,n;
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&A,&B,&C,&D,&P,&n);
        f[1] = A;
        f[2] = B;
        Mat m;
        m.init();
        m.d[0][0] = D,m.d[1][0] = C;
        m.d[0][1] = 1,m.d[2][2] = 1;
        ll l,r;
        ll f1 = f[2],f2 = f[1];
        for(ll i = 3; i<=n;i = r +1)
        {
            r = (P / i == 0 ? n : min(n,P/(P/i)));
            //cout<
            m.d[2][0] = P/i;
            Mat ans = pow_mod(m,r -i+1);
            //ans.show();
            f[3] = (f1 * ans.d[0][0]% mod + f2 * ans.d[1][0] % mod+ ans.d[2][0]) % mod;
            f[4] = (f1 * ans.d[0][1]% mod + f2 * ans.d[1][1]% mod + ans.d[2][1]) % mod;
            f1 = f[3];
            f2 = f[4];
        }
        printf("%I64d\n",f1);
    }
    return 0;
}

1011 Swordsman
题意是战士砍怪,都各自有K个属性,每个属性必须比怪物都高才能砍死,砍死之后属性会对应提升,问最后砍死的怪和提升到最高的属性
建K个堆,先把所有的怪物放到第一个堆,然后把当前能打的都推到下一个堆里,直到增加不了砍死怪物数量。

#include 
#define ll long long
using namespace std;
namespace fastIO {
    #define BUF_SIZE 100000
    //fread -> read
    bool IOerror = 0;
    inline char nc() {
        static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
        if(p1 == pend) {
            p1 = buf;
            pend = buf + fread(buf, 1, BUF_SIZE, stdin);
            if(pend == p1) {
                IOerror = 1;
                return -1;
            }
        }
        return *p1++;
    }
    inline bool blank(char ch) {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    inline void read(int &x) {
        char ch;
        while(blank(ch = nc()));
        if(IOerror) return;
        for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
    }
    #undef BUF_SIZE
};
using namespace fastIO;
const int maxn = 2e5 + 5;
struct knode
{
    int k;
    int id;
    friend operator < (const knode &a,const knode &b)
    {
        return a.k > b.k;
    }
    knode(int _k,int _id){k = _k,id = _id;}
};
int v[10];
int a[maxn][6];
int b[maxn][6];
priority_queue q[6];
int main()
{
    int ca;
    read(ca);
    while(ca--)
    {
        int n,k;
        read(n),read(k);
        for(int i = 0;iwhile(!q[i].empty()) q[i].pop();
            read(v[i]);
        }
        for(int i  =0;ifor(int j = 0;jread(a[i][j]);
            }
            q[0].push(knode(a[i][0],i));
            for(int j = 0;jread(b[i][j]);
            }
        }
        int ans = 0;
        while(1)
        {
            int org = ans;
            for(int i = 0;i1;i++)
            {
              //  cout<<"NOW :"<while(!q[i].empty() && q[i].top().k <= v[i])
                {
                    int x = q[i].top().id;
                   // cout<<"Next :"<<x<q[i].pop();
                    q[i+1].push(knode(a[x][i+1],x));
                }
            }
            while(!q[k-1].empty() && q[k-1].top().k <= v[k-1])
            {
                int x = q[k-1].top().id;
              //  cout<<"Get "<<x<q[k-1].pop();
                ans++;
                for(int i = 0;ix][i];
                    //cout<' ';
                }
                //cout<if(ans == org) break;
        }
        printf("%d\n",ans);
        for(int i = 0;iprintf("%d%c",v[i]," \n"[i == k-1]);
        }
    }
    return 0;
}

你可能感兴趣的:(2018多校题解)