2019 ICPC南昌ネットワークゲーム

2019 ICPC南昌ネットワークゲーム

マッチタイム:2019年9月8日
ゲームリンク:2019年アジアオンライン・プログラミング・コンテスト南昌ファーストラウンドで

概要 //最高ランクの歴史、開口部、2時間未満、それぞれのタイトル4つの質問の合計タイトルをチームメイトの後、水を加え、インスタント順位は、3つまたは4つの10 //に上昇した後、自閉症の3時間後に、問題を壊しませんでした。最後に211 HHHH位にランク

 


 

B.消火ヒーロー

問題の意味

彼のチームメイトは、完了するために行います。
 

ACコード

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N = 2010;
int head[N],cnt;
struct node
{
    int v,nxt,w;
}e[N*N];
void addedge(int u,int v,int w)
{
    e[cnt].v= v;
    e[cnt].nxt = head[u];
    e[cnt].w = w;
    head[u] = cnt++;
}
int dis[N];
int mp[N][N];
queue<int>q;
int vis[N];
void spfa()
{
    while(!q.empty())
    {
        int u = q.front();
        //cout<<u<<endl;
        q.pop();
        vis[u] = 0;
        for(int i=head[u];~i;i=e[i].nxt)
        {
            int v = e[i].v;
            //cout<<" "<<v<<endl;
            if(dis[v]>dis[u]+mp[u][v])
            {
                dis[v] = dis[u]+mp[u][v];
                if(vis[v]==0)
                {
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        memset(head,-1,sizeof(head));
        cnt = 0;
        int V,E,S,K,C;
        scanf("%d%d%d%d%d",&V,&E,&S,&K,&C);
        for(int i=1;i<=V;++i)
        {
            vis[i]=0;
            dis[i]=(1<<30);
            for(int j=1;j<=V;++j)
                mp[i][j]=(1<<30);
        }   
        for(int i=1;i<=K;++i)
        {
            int d;scanf("%d",&d);
            dis[d] = 0;
            q.push(d);
            vis[d] = 1;
        }
        for(int i=1;i<=E;++i)
        {
            int u,v,w;scanf("%d%d%d",&u,&v,&w);
            if(mp[u][v]==(1<<30))
            {
                addedge(u,v,w);
                addedge(v,u,w);
            }
            mp[u][v]=mp[v][u]=min(mp[u][v],w);
        }
        spfa();
        int ptr = 0;
        for(int i=1;i<=V;++i)
            if(dis[i]!=(1<<30))
                ptr = max(ptr,dis[i]);
        for(int i=1;i<=V;++i)
        {
            vis[i] = 0;
            dis[i]=(1<<30);
        }
        dis[S] = 0;
        while(!q.empty())q.pop();
        q.push(S);
        vis[S] = 1;
        spfa();
        int hero = 0;
        for(int i=1;i<=V;++i)
            if(dis[i]!=(1<<30))
                hero = max(hero,dis[i]);
        if(hero<=ptr*C)
            printf("%d\n",hero);
        else
            printf("%d\n",ptr);
    }
    return 0;
}

 

E.マジックマスター

問題の意味

テーブルトランプのNスタックは、各カードには、次の2つのプロセスで取り出した数(1〜N)を、持っています:

  1. の手に、ポーカーのカードのこの山の頂上を削除します。手持ちのカードがあり、その後、底にすべてのカードを置きます。
  2. テーブルの上にカードが残っている場合は、挿入部、操作のM回の最後に、テーブルの上に置きます。
    降順に番号カードの最後の手場合は、表は、各カードの番号を模索し始めました。Qは時間が与えられているK-カード番号の上から下に各テーブルを尋ねています。
     

考え

彼らは最初の数をシミュレートする直接計算することができますように、ラフな数を起動します。見つかっ終了したことリーチの複雑さ(O(QN ^ 2)\)\、断言T.
払っていないコードをつかんで、それが唯一最大のQ 100は、その後、結果は100回のクエリの処理のみ前であることが判明した、長い時間のためのサンプル曲は尽きませんでした。
printf非常に似たマークのメモリに結合され、良好な結果を有することが見出さ最初のオペレータが、デバッグ。その後A.まで支払います
彼らはTを行う理由は試合後、私は兄がこのヨセフスに対処する方法には言いませんでした、私は、ああ、これはヨセフスです実現しています
私はSTLを使用することができqueue、非常に良い右O(¯▽¯)O
 

ACコード

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 40000010;

int n, m;
int ans[maxn], now;

queue<int> q;
void solve(int k) {
    if(ans[k]!=-1) {
        printf("%d\n", ans[k]);
        return;
    }
    while(q.size()) {
        int num = q.front();  q.pop();
        ans[num] = ++now;

        bool flag = 0;
        if(num==k) {
            printf("%d\n", ans[k]);
            flag = true;
        }
        
        if(q.empty()) break;
        for(int i=1;i<=m;i++) {
            int num = q.front();  q.pop();
            q.push(num);
        }

        if(flag) break;
    }
}

int main() {
    int T; cin>>T;
    while(T--) {
        int Q;
        scanf("%d %d %d", &n, &m, &Q);
        
        memset(ans, -1, sizeof(ans));
        while(q.size()) q.pop();
        for(int i=1;i<=n;i++) q.push(i);
        now = 0;
        while(Q--) {
            int k;
            scanf("%d", &k);
            solve(k);
        }
    }
    
    return 0;
}

 

G. Panguは天と地を区切り

問題の意味

出席の問題。
 

ACコード

わずか。
 

H.ザ・N番目の項目

問題の意味

定義
\ [F(0)= 0
、F(1)= 1 \\ F(N)= 3 * F(N-1)+ 2 * F(N-2)、(≧2)\] が存在\ (Q \)倍問合せ要求\(F.(N)\) \(1 \のLeq Q \ ^のLeq 10 7、0 \のLeq N \のLeq 18は10 ^ {} \)
 

考え

彼のチームメイトを感じるようになったBM線形回帰を行うことができますが、私は喜んでTLEを変更するために変更するためにボード上のポストを取りました。
それから私は、2つのあなたが完全に線形回帰ああ、十分に迅速に直接行列パワーません見ました。
私は、高速行列パワーを書き込み、中間結果が生き残る促しながら、チームメイトが最適化する方法を見つけてみましょう。
そして、データのセットを構築するチームメイトが、私は彼がACを支払ったように、Tは、直線外挿利きです。
 

ACコード

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
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 all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())

typedef long long ll;
typedef vector<ll> VLL;
const ll mod = 998244353;

ll powmod(ll a, ll b) {
    ll res=1;a%=mod;
    for(;b;b>>=1) {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
    }
    return res;
}

namespace linear_seq {
    const int N = 100010;
    ll res[N], base[N], _c[N], _md[N];

    VLL Md;
    void mul(ll a[], ll b[], int k) {
        for(int i=0;i<k+k;i++)
            _c[i] = 0;
        for(int i=0;i<k;i++)
            if(a[i])
                for(int j=0;j<k;j++)
                    _c[i+j] = (_c[i+j] + a[i]*b[j]%mod) % mod;

        for(int i=k+k-1;i>=k;i--) 
            if(_c[i])
                rep(j,0,SZ(Md))
                    _c[i-k+Md[j]] = (_c[i-k+Md[j]] - _c[i] * _md[Md[j]]%mod) % mod;

        for(int i=0;i<k;i++)
            a[i] = _c[i];
    }

    ll solve(ll n, VLL a, VLL b) {
        ll ans = 0, pnt = 0;
        int k = SZ(a);
        for(int i=0;i<k;i++)
            _md[k-1-i]=-a[i];
        _md[k]=1;

        Md.clear();
        for(int i=0;i<k;i++)
            if(_md[i]!=0) Md.push_back(i);
        for(int i=0;i<k;i++)
            res[i]=base[i]=0;
        res[0]=1;

        while((1ll<<pnt)<=n) pnt++;
        for(int p=pnt;p>=0;p--) {
            mul(res, res, k);
            if((n>>p)&1) {
                for(int i=k-1;i>=0;i--)
                    res[i+1]=res[i];res[0]=0;
                rep(j,0,SZ(Md))
                    res[Md[j]]=(res[Md[j]] - res[k]*_md[Md[j]]%mod) % mod;
            }
        }

        for(int i=0;i<k;i++)
            ans = (ans + res[i]*b[i]%mod) % mod;
        if(ans<0) ans += mod;
        return ans;
    }

    VLL BM(VLL s) {
        VLL C(1,1), B(1,1);
        int L=0,m=1,b=1;
        rep(n,0,SZ(s)) {
            ll d=0;
            rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i]%mod) % mod;
            if(d==0) ++m;
            else if(2*L<=n) {
                VLL T=C;
                ll c=mod-d*powmod(b,mod-2)%mod;
                while(SZ(C)<SZ(B)+m) C.pb(0);
                rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i]%mod) % mod;
                L=n+1-L; B=T; b=d; m=1;
            } else {
                ll c = mod- d*powmod(b, mod-2)%mod;
                while(SZ(C)<SZ(B)+m) C.pb(0);
                rep(i,0,SZ(B))
                    C[i+m]=(C[i+m]+c*B[i]%mod) % mod;
                ++m;
            }
        }
        return C;
    }
};

VLL a, c;
ll fib[110];

void init() {
    fib[1] = 1;
    for(int i=2;i<110;i++) {
        fib[i] = (3*fib[i-1] + 2*fib[i-2]) % mod;
    } 

    for(int i=1;i<=100;i++) {
        a.pb(fib[i]);
    }

    c = linear_seq::BM(a);
    c.erase(c.begin());
    rep(i,0,SZ(c))
    c[i] = (mod-c[i])%mod;
}

map<ll,ll>mp;
int main() {
    init();

    int T; ll N;
    scanf("%d %lld", &T, &N);
    ll RES = 0;
    ll ans = 0;
    while(T--) {
        N = (ans*ans)^N;
        if(mp[N]) ans = mp[N];
        else ans = linear_seq::solve(N-1, c, VLL(a.begin(), a.begin()+SZ(c)));
        mp[N]=ans;
        RES ^= ans;
        // printf("%lld\n", ans);
    }
    printf("%lld\n", RES);
    return 0;
}

/*
卡矩阵快速幂的数据
10000000 473844410
*/

 


 
(未完を完了すること。)

おすすめ

転載: www.cnblogs.com/izcat/p/11495097.html