2018多校联合训练7

http://acm.hdu.edu.cn/contests/contest_show.php?cid=808

只过了4题

 

1005:莫比乌斯反演/容斥原理,一开始TLE了两发,把求逆元long long改成int就过了,卡常

solved by lyy

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 1000000
int n,m,p,t;
const int MAXN = 1000000;
bool check[MAXN+10];
int phi[MAXN+10];
int prime[MAXN+10];
int tot;
void phi_and_prime_table(int N)
{
    memset(check,false,sizeof(check));
    phi[1] = 1;
    tot = 0;
    for(int i = 2; i <= N; i++)
    {
        if( !check[i] )
        {
            prime[tot++] = i;
            phi[i] = i-1;
        }
        for(int j = 0; j < tot; j++)
        {
            if(i * prime[j] > N)break;
            check[i * prime[j]] = true;
            if( i % prime[j] == 0)
            {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            else
            {
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
        }
    }
}

ll inv(int a,int m)
{
    if(a == 1)return 1;
    return inv(m%a,m)*(m-m/a)%m;
}

int pri[maxn+5];
int mu[maxn+5];
void getMu()
{
    int i,j;
    mu[1]=1;
    for (i=2;i<=maxn;i++)
    {
        if (pri[i]==0) 
        {
            pri[++pri[0]]=i;
            mu[i]=-1;
        }
        for (j=1;j<=pri[0] && pri[j]<=maxn/i;j++)
        {
            pri[pri[j]*i]=1;
            if (i%pri[j])
                mu[i*pri[j]]=-mu[i];
            else
            {
                mu[i*pri[j]]=0;
                break;
            }
        }
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    phi_and_prime_table(MAXN);
    getMu();
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d%d%d",&n,&m,&p);
        ll ans=0;
        for (int i=1;i<=min(n,m);i++)
        {
            int k1=n/i;
            int k2=m/i;
            ll cnt=0;
            for (int j=1;j<=min(k1,k2);j++)
            {
                if (mu[j]==1) cnt+=(ll)(k1/j)*(k2/j);
                else if (mu[j]==-1) cnt-=(ll)(k1/j)*(k2/j);
            }
            cnt%=p;
            cnt=cnt*i%p*inv(phi[i],p)%p;
            ans=(ans+cnt)%p;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

1001:优先队列+BFS,貌似题目/标程有问题???

solved by sdn

/*
  ID: oodt
  PROG:
  LANG:C++
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<cassert>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<set>

using namespace std;

#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}

const int maxx = 4000500;
const int INF = 0x3f3f3f3f;
int n,m,k;
int a[maxx];
int vis[maxx];
int ans = 0,cnt = 0,pos = 0;
int l = 0,r = 0;
struct Edge {
    int to,next,w;
}edge[maxx];
struct pp{
    int d;
    int u;
    int fa;
    int par;
    bool operator < (const pp &r)const{
        return d > r.d;
    }
};
int head[maxx],tot;

void addedge(int u,int v,int w)
{
    edge[tot].to = v;
    edge[tot].next = head[u];
    edge[tot].w = w;
    head[u] = tot++;
}
int dd[maxx];
void init(){
    tot = 0;
    memset(dd,0x3f,sizeof(dd));
    memset(head,-1,sizeof(head));
    memset(vis,0,sizeof(vis));
}

int bfs(){
    priority_queue<pp> q;
    pp a;
    a.d = 0;
    a.u = 1;
    dd[a.u] = 0;
    a.fa = -1;
    a.par = -1;
    q.push(a);
    while(!q.empty()){
        pp u = q.top();
        q.pop();
        if(u.u == n){
            return u.d;
        }
        if(dd[u.u] < u.d) continue;
        dd[u.u] = min(u.d,dd[u.u]);
        for(int i = head[u.u]; i != -1; i = edge[i].next){
            int v = edge[i].to;
            if(v == u.par) continue;
            pp b;
            b.u = v;
            b.par = u.u;
            if(edge[i].w == u.fa) b.d = u.d;
            else b.d = u.d + 1;
            b.fa = edge[i].w;
//            printf("%d %d %d %d %d\n",u.u,v,u.d,edge[i].w,u.fa);
            q.push(b);
        }
    }
    return -1;
}

int main()
{
#ifdef LOCAL
//    freopen("","r",stdin);
#endif
    while(~scanf("%d%d",&n,&m))
    {
        init();
        rep(i,0,m){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        ans = bfs();
        printf("%d\n",ans);
    }
    return 0;
}

 

1011:卡IO,用输入输出外挂还是T了,换fread就过了

solved by lyy and wyq

include <bits/stdc++.h>
using namespace std;
#define ll long long
int t,n,k;
int v[10];
struct st
{
    int id;
    int data;
}a[8][100005];
int h[100005];
int cnt[10];
int b[8][100005];
namespace IO {
    const int MX = 4e7;
    char buf[MX]; int c, sz;
    void begin() {
        c = 0;
        sz = fread(buf, 1, MX, stdin);
    }
    inline bool read(int &t) {
        while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;
        if(c >= sz) return false;
        bool flag = 0; if(buf[c] == '-') flag = 1, c++;
        for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';
        if(flag) t = -t;
        return true;
    }
}
bool cmp(st a,st b)
{
    return a.data<b.data;
}

int main()
{
    //freopen("in.txt","r",stdin);
    IO::begin();
    IO::read(t);
    while (t--)
    {
        memset(h,0,sizeof(h));
        memset(cnt,0,sizeof(cnt));
        IO::read(n);IO::read(k);
        for (int i=1;i<=k;i++)
        {
            IO::read(v[i]);
        }
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=k;j++)
            {
                IO::read(a[j][i].data);
                a[j][i].id=i;
            }
            for (int j=1;j<=k;j++)
            {
                IO::read(b[j][i]);
            }
        }
        for (int i=1;i<=k;i++)
        {
            sort(a[i]+1,a[i]+n+1,cmp);
        }
        int ans=0;

        while (1)
        {
            int can=0;
            int isbreak=0;
            for (int i=1;i<=k;i++)
            {
                while (cnt[i]<n && a[i][cnt[i]+1].data<=v[i])
                {
                    cnt[i]++;
                    h[a[i][cnt[i]].id]++;
                    //cout<<a[i][cnt[i]].id<<' '<<i<<endl;
                    if (h[a[i][cnt[i]].id]==k)
                    {
                        ans++;
                        can=1;
                        for (int j=1;j<=k;j++)
                        {
                            v[j]+=b[j][a[i][cnt[i]].id];
                        }
                        isbreak=1;
                        break;
                    }
                }
                if(isbreak==1)break;
            }
            if (can==0) break;
        }
        printf("%d\n",ans);
        for (int i=1;i<=k;i++)
        {
            printf("%d",v[i]);
            if (i!=k) printf(" ");
        }
        printf("\n");
    }
    return 0;
}

 

1010:矩阵快速幂,队友想出来嫌比较烦就扔给我来写了

solved by wyq

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1000000007;
int C,D,P,n;
ll f[100005];

struct Matrix
{
    long long m[3][3];
    Matrix()
    {
        memset(m,0,sizeof(m));
        for(int i=0;i<3;i++)
            m[i][i] = 1LL;
    }
};
Matrix Mul(Matrix a, Matrix b){
    Matrix ans;
    for(int i=0;i<3;++i){
        for(int j=0;j<3;++j){
            ans.m[i][j] = 0;
            for(int k=0;k<3;++k){
                ans.m[i][j] += a.m[i][k] * b.m[k][j];
                ans.m[i][j] %= mod;
            }
        }
    }
    return ans;
}

struct mat2
{
    ll m[3];
    mat2(){}
    mat2(ll a,ll b,ll c)
    {
        m[0]=a;
        m[1]=b;
        m[2]=c;
    }
};

Matrix fastm(Matrix a,int b)
{
    Matrix res;
    while(b)
    {
        if(b&1)
        res = Mul(res,a);
        a = Mul(a,a);
        b >>= 1;
    }
    return res;
}

Matrix e()
{
    Matrix x;
    x.m[0][0]=D;x.m[0][1]=C;x.m[0][2]=1;
    x.m[1][0]=1;x.m[1][1]=0;x.m[1][2]=0;
    x.m[2][0]=0;x.m[2][1]=0;x.m[2][2]=1;
    return x;
}

mat2 mul(Matrix a,mat2 b)
{
    mat2 x=mat2(0,0,0);
    for (int i=0;i<3;i++)
    {
        for (int j=0;j<3;j++)
        {
            x.m[i]=(x.m[i]+a.m[i][j]*b.m[j])%mod;
        }
    }
    return x;
}
    

void solve(mat2 &x,int l,int r)
{
    if (l>r) return;
    Matrix d=e();
    d=fastm(d,r-l+1);
    x=mul(d,x);
}


int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%lld%lld%d%d%d%d",&f[1],&f[2],&C,&D,&P,&n);
        for (int i=3;i<=100000;i++)
        {
            f[i]=(C*f[i-2]+D*f[i-1]+P/i)%mod;
        }
        if (n<=100000)
        {
            printf("%lld\n",f[n]);
            continue;
        }
        else
        {
            ll a=f[99999];
            ll b=f[100000];
            int x=100000;
            mat2 y(b,a,P/(x+1));
            while (x<n)
            {
                y.m[2]=P/(x+1);
                if (P>=(x+1))
                {
                    //cout<<x+1<<' '<<P/(P/(x+1))<<endl; 
                    solve(y,x+1,min(n,P/(P/(x+1))));
                    x=min(n,P/(P/(x+1)));
                }
                else
                {
                    solve(y,x+1,n);
                    x=n;
                }
                //cout<<x<<' '<<y.m[0]<<' '<<f[x]<<endl;
            }
            printf("%lld\n",y.m[0]);
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值