2017 Multi-University Training Contest

rank 71

1002 Array Challenge

BM算法

#include <bits/stdc++.h>

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 long long ll;
typedef vector<ll> VI;

typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// head

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

    vector<int> Md;
    void mul(ll *a,ll *b,int k) {
        rep(i,0,k+k) _c[i]=0;
        rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%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;
        rep(i,0,k) a[i]=_c[i];
    }
    int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
//        printf("%d
",SZ(b));
        ll ans=0,pnt=0;
        int k=SZ(a);
        assert(SZ(a)==SZ(b));
        rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
        Md.clear();
        rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
        rep(i,0,k) 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;
            }
        }
        rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
        if (ans<0) ans+=mod;
        return ans;
    }
    VI BM(VI s) {
        VI 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;
            if (d==0) ++m;
            else if (2*L<=n) {
                VI 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;
                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;
                ++m;
            }
        }
        return C;
    }
    int gao(VI a,ll n) {
        VI c=BM(a);
        c.erase(c.begin());
        rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
        return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
    }
};
ll b,a;
ll bb[20],aa[20],h[20];
ll n;
vector<ll>vec;
int main() {
   // freopen("data.out","w",stdout);
    h[0]=2;h[1]=3;h[2]=6;
    for(int i=3;i<=11;i++) {
        h[i]=(4*h[i-1]+17*h[i-2]-12*h[i-3]-16);
    }
    for(int i=2;i<=10;i++) {
        bb[i]=(3*h[i+1]*h[i]+9*h[i+1]*h[i-1]+9*h[i]*h[i]+27*h[i]*h[i-1]-18*h[i+1]-126*h[i]-81*h[i-1]+192)+(1LL<<(2*i));
        ll tmp=(ll)(sqrt(bb[i]))%mod;
        vec.push_back(tmp);
    }
    for (scanf("%d",&_);_;_--) {
        scanf("%I64d",&n);
        b=linear_seq::gao(vec,n-2);
        printf("%I64d
",b%mod);
    }
}
View Code

1008 Monkeys

二二猴子配对

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
namespace fastIO{
    #define BUF_SIZE 100000
    #define OUT_SIZE 100000
    #define ll long long
    //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;}
            //{printf("IO error!
");system("pause");for (;;);exit(0);}
        }
        return *p1++;
    }
    inline bool blank(char ch){return ch==' '||ch=='
'||ch=='
'||ch=='	';}
    inline int read(int &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return 0;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
        return 1;
    }
    inline int read(ll &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return 0;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
        return 1;
    }
    inline int read(double &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return 0;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (ch=='.'){
            double tmp=1; ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
        }
        if (sign)x=-x;
        return 1;
    }
    inline int read(char *s){
        char ch=nc();
        for (;blank(ch);ch=nc());
        if (IOerror)return 0;
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
        return 1;
    }
    inline void read(char &c){
        for (c=nc();blank(c);c=nc());
        if (IOerror){c=-1;return;}
    }
    //fwrite->write
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        void out(char ch){
            if (p1==pend){
                fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
            }
            *p1++=ch;
        }
        void print(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('
');
        }
        void print(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('
');
        }
        void print(double x,int y){
            static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
                1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
                100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
            if (x<-1e-12)out('-'),x=-x;x*=mul[y];
            ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
            ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
            if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
        }
        void println(double x,int y){print(x,y);out('
');}
        void print(char *s){while (*s)out(*s++);}
        void println(char *s){while (*s)out(*s++);out('
');}
        void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
        ~Ostream_fwrite(){flush();}
    }Ostream;
    inline void print(int x){Ostream.print(x);}
    inline void println(int x){Ostream.println(x);}
    inline void print(char x){Ostream.out(x);}
    inline void println(char x){Ostream.out(x);Ostream.out('
');}
    inline void print(ll x){Ostream.print(x);}
    inline void println(ll x){Ostream.println(x);}
    inline void print(double x,int y){Ostream.print(x,y);}
    inline void println(double x,int y){Ostream.println(x,y);}
    inline void print(char *s){Ostream.print(s);}
    inline void println(char *s){Ostream.println(s);}
    inline void println(){Ostream.out('
');}
    inline void flush(){Ostream.flush();}
};
using namespace fastIO;
struct edge{
    int to,next;
}E[212345];
int head[112345];
int sum[112345];
int nu[112345];
int ans = 0,tot,maxn;
int dfs(int u,int f){
    int num = 0;
    for (int i = head[u]; i!=-1 ; i = E[i].next){
        int to = E[i].to;
        if (to == f) continue;
        if (dfs(to,u) == 0) num++;
    }
    if (num>=1){
        sum[num+1]++;
        ans++;
        maxn = max(maxn,num+1);
    }
    nu[u] = num+1;
    return num;
}
int main()
{
    int T;
    read(T);
    while(T--) {
        int N,K;
        int a;
        ans = 0;
        read(N);
        read(K);
        for (int i = 1;i<=N;i++)
            head[i] = -1,sum[i] = 0;
        tot = 0;
        for (int i = 1; i<N;i++){
            read(a);
            E[tot].next = head[a];
            E[tot].to = i+1;
            head[a] = tot++;

            E[tot].next = head[i+1];
            E[tot].to = a;
            head[i+1] = tot++;
        }
        maxn = 0;
        dfs(1,0);
        if (nu[1] == 1){
            int to = E[head[1]].to;
            int num = nu[to];
            sum[num]--;
            sum[num+1]++;
        }
        int le = N-K;
        for (int i = maxn+1; i>=3; i--){
            if (sum[i] < le){
                le -= sum[i];
                ans += sum[i];
                sum[i-1] += sum[i];
            }
            else {
                ans += le;
                le = 0;
                break;
            }
        }
        if (le > 0){
            ans += (le/2);
        }
        print(N-ans);
        print('
');
    }
}
View Code

1010 Schedule

贪心

#include <bits/stdc++.h>
#define maxn 100010
#define inf 0x3f3f3f3f
#define REP(i,x,y) for(int i=x;i<(y);i++)
#define RREP(i,x,y) for(int i=x;i>(y);i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
pii t[maxn];
set<pii>S;
int ans,n;
pii vec[maxn];
int main()
{
    int T;scanf("%d",&T);
    while(T--) {
        S.clear();memset(vec,0,sizeof(vec));memset(t,0,sizeof(t));
        ans=0;scanf("%d",&n);
        REP(i,1,n+1)
            scanf("%d %d",&t[i].first,&t[i].second);
        sort(t+1,t+1+n);
        S.insert(make_pair(t[1].second,1));
        vec[++ans]=make_pair(t[1].first,t[1].second);
        REP(i,2,n+1) {
            auto it=S.upper_bound(make_pair(t[i].first,inf));
            if(it!=S.begin()) {
                it--;
                int tmp=(*it).second;
                vec[tmp].second=t[i].second;
                S.erase(it);
                S.insert(make_pair(t[i].second,tmp));
            }
            else {
                vec[++ans]=make_pair(t[i].first,t[i].second);
                 S.insert(make_pair(t[i].second,ans));
            }
        }
        printf("%d ",ans);
        ll sum=0;
        REP(i,1,ans+1) sum+=vec[i].second-vec[i].first;
        printf("%I64d
",sum);
    }
}
View Code

1011 Two Paths

次短路

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#define maxn 100040
#define inf 0x3f3f3f3f3f3f3f3f

using namespace std;
typedef long long ll;
template <class T>
inline void read(T &res){
    char c;res=0;
    while((c=getchar())<'0'||c>'9');
    while(c>='0'&&c<='9'){
        res=res*10+(c-'0');
        c=getchar();
    }
}
//////
struct edge{
    int to;
    long long cost;
    edge(){}
    edge(int _to,int _cost):to(_to),cost(_cost){}
};
vector<edge>e[maxn];
int vis[maxn];
long long dis1[maxn],dis2[maxn];
int flag[maxn];
int pre[maxn];
int n,r;
long long spfa(){
    queue<int>que;que.push(1);
    memset(dis1,inf,(n+1) * sizeof (dis1[0]));
    memset(pre,-1,(n+1) * sizeof (pre[0]));
    memset(vis,0,(n+1) * sizeof (vis[0]));
    memset(dis2,inf,(n+1) * sizeof (dis2[0]));
    memset(flag,0,(n+1) * sizeof (flag[0]));

    vis[1]=0;dis1[1]=0;
    while(!que.empty()){
        int now=que.front();que.pop();
        for(int i=0;i<e[now].size();i++){
            int Next=e[now][i].to;int len=e[now][i].cost;
            if(dis1[Next]>dis1[now]+len){
                dis2[Next]=min(dis2[now]+len,dis1[Next]);
                dis1[Next]=dis1[now]+len;
                pre[Next] = now;
                flag[Next] = flag[now];
                if(!vis[Next]){
                    vis[Next]=1;que.push(Next);
                }
            }
            else if(dis1[Next]==dis1[now]+len&&dis2[Next]>dis2[now]+len){
                if (pre[Next]!=now) {flag[Next] = 1;pre[Next] = -1;}
                dis2[Next]=dis2[now]+len;
                if(!vis[Next]){
                    vis[Next]=1;que.push(Next);
                }
            }
            else if(dis1[Next]<dis1[now]+len&&dis2[Next]>dis1[now]+len){
                dis2[Next]=dis1[now]+len;
                if(!vis[Next]){
                    vis[Next]=1;que.push(Next);
                }
            }
            else if (dis1[Next]==dis1[now]+len){
                if (pre[Next]!=now) {flag[Next] = 1;pre[Next] = -1;}
            }
        }
        vis[now]=0;
    }
    if (flag[n]) return dis1[n];
    else return dis2[n];
}
int main()
{
    int t;
    read(t);
    while (t--){
    read(n);read(r);
    for (int i = 1; i<=n;i++)
        e[i].clear();
    for(int i=1;i<=r;i++) {
        int u,v,c;read(u),read(v),read(c);
        e[u].push_back(edge(v,c));e[v].push_back(edge(u,c));
    }
    printf("%lld
",spfa());
    }
}
View Code
原文地址:https://www.cnblogs.com/HITLJR/p/7536854.html