2017 Multi-University Training Contest

1002 Ch’s gift

垃圾题。暴力和主题树都能过。

#include <bits/stdc++.h>
using namespace std;
const int maxn=100005;
int n,m,fa[maxn],s,t,x,y,d[maxn],head[maxn],nxt[maxn<<1],to[maxn<<1],cnt;
long long a[maxn];
void dfs(int u,int f) {
    fa[u]=f;
    for (int i=head[u];~i;i=nxt[i]) {
        int v=to[i];
        if (v==f)
            continue;
        d[v]=d[u]+1;
        dfs(v,u);
    }
}
inline long long solve(int s,int t,int x,int y) {
    long long ret=0;
    if (d[s]<d[t])
        swap(s,t);
    while (d[s]!=d[t]) {
        ret+=(a[s]>=x&&a[s]<=y)?a[s]:0;
        s=fa[s];
    }
    while (s!=t) {
        ret+=(a[s]>=x&&a[s]<=y)?a[s]:0;
        ret+=(a[t]>=x&&a[t]<=y)?a[t]:0;
        s=fa[s];
        t=fa[t];
    }
    return ret+((a[s]>=x&&a[s]<=y)?a[s]:0);
}
int main()
{
    while (scanf("%d%d",&n,&m)==2) {
        cnt=0;
        for (int i=1;i<=n;++i) {
            scanf("%I64d",&a[i]);
            head[i]=-1;
        }
        for (int i=0;i<n-1;++i) {
            int u,v;
            scanf("%d%d",&u,&v);
            nxt[cnt]=head[u];
            to[cnt]=v;
            head[u]=cnt++;
            nxt[cnt]=head[v];
            to[cnt]=u;
            head[v]=cnt++;
        }
        d[0]=0;
        dfs(1,0);
        while (m--) {
            scanf("%d%d%d%d",&s,&t,&x,&y);
            printf("%I64d%c",solve(s,t,x,y),!m?'
':' ');
        }
    }
    return 0;
}
暴力
#include <bits/stdc++.h>
#define maxn 100010
//#define OPENSTACK
#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;
int a[100010],head[100010];
vector<int>e[maxn];
int all[100010];
int root[maxn],ls[maxn*18],rs[maxn*18];
ll sum[maxn*18];
int tot;
void Insert(int& rt,int pre,int pos,ll val,int l,int r) {
    rt=(++tot);
    sum[rt]=sum[pre]+val;
    if(l==r) return ;
    if(pos<=((l+r)>>1)) {
        ls[rt]=0;rs[rt]=rs[pre];
        Insert(ls[rt],ls[pre],pos,val,l,(l+r)>>1);
    }
    else {
        ls[rt]=ls[pre];rs[rt]=0;
        Insert(rs[rt],rs[pre],pos,val,((l+r)>>1)+1,r);
    }
}
ll query(int pre,int rt,int ql,int qr,int l,int r){
    if(ql<=l&&r<=qr)
        return sum[rt]-sum[pre];
    int m=(l+r)>>1;
    ll res=0;
    if(ql<=m) res=res+query(ls[pre],ls[rt],ql,qr,l,m);
    if(qr>m) res=res+query(rs[pre],rs[rt],ql,qr,m+1,r);
    return res;
}
int m;
int dis[100010],n,par[100010][18];
void dfs(int rt,int len,int fa){
    root[rt]=0;
    Insert(root[rt],root[fa],a[rt],all[a[rt]],1,m);
    dis[rt]=len;
    for(int i=0;i<e[rt].size();i++) {
        if(fa==e[rt][i]) continue;
        par[e[rt][i]][0]=rt;
        dfs(e[rt][i],len+1,rt);
    }
}
void init(){
    memset(par,0,sizeof(par));
    dis[1]=0;
    dfs(1,0,0);
    for(int j=1;(1<<j)<=n;j++)
    REP(i,1,n+1)
        if(par[i][j-1]!=0)
            par[i][j]=par[par[i][j-1]][j-1];
}
int k;
int LCA(int a,int b){
    if(dis[a]<dis[b]) swap(a,b);
    k=0;while((1<<(k+1))<=dis[a]) k++;
    RREP(j,k,-1)
        if(dis[a]-(1<<j)>=dis[b])
            a=par[a][j];
    RREP(i,k,-1)
        if(par[a][i]!=0&&par[a][i]!=par[b][i])
            a=par[a][i],b=par[b][i];
    if(a==b) return a;
    return par[a][0];
}
int q,b[100010];
int main()
{
    while(scanf("%d %d",&n,&q)==2) {
        tot=0;
        for(int i=0;i<=n;i++) e[i].clear();
        memset(root,0,sizeof(root));
        REP(i,1,n+1) {
            scanf("%d",&a[i]);
            all[i]=a[i];
            b[i]=a[i];
        }
        REP(i,1,n) {
            int u,v;scanf("%d %d",&u,&v);
            e[u].push_back(v);
            e[v].push_back(u);
        }
        sort(all+1,all+1+n);
        m=unique(all+1,all+1+n)-all-1;//cout<<m<<endl;
        REP(i,1,n+1)
            a[i]=lower_bound(all+1,all+1+m,a[i])-all;
        init();
        REP(i,1,q+1) {
            int s,t,A,B;scanf("%d %d %d %d",&s,&t,&A,&B);
            A=lower_bound(all+1,all+1+m,A)-all;
            B=upper_bound(all+1,all+1+m,B)-all;
            B--;
            if(A>B)
                printf("%d%c",0 , " 
"[i==q]);
            else {
                int lca=LCA(s,t);
                ll sum1=query(root[par[lca][0]],root[s],A,B,1,m);
                ll sum2=query(root[par[lca][0]],root[t],A,B,1,m);
                ll tmp=b[lca];
                if(tmp>=all[A]&&tmp<=all[B]) sum1-=tmp;
                printf("%I64d%c", sum1+sum2, " 
"[i==q]);
            }
        }
    }
}
主题树

1005 FFF at Valentine

floyd+bitset闭包

#include <bits/stdc++.h>
using namespace std;
int T,n,m;
bitset<1001> bit[1001];
inline bool check() {
    for (int i=1;i<=n;++i)
        for (int j=i+1;j<=n;++j)
            if (!bit[i][j]&&!bit[j][i])
                return false;
    return true;
}
int main()
{
    scanf("%d",&T);
    while (T--) {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;++i) {
            bit[i].reset();
            bit[i][i]=1;
        }
        for (int i=0;i<m;++i) {
            int u,v;
            scanf("%d%d",&u,&v);
            bit[u][v]=1;
        }
        for (int i=1;i<=n;++i)
            for (int j=1;j<=n;++j)
                if (bit[j][i])
                    bit[j]|=bit[i];
        puts(check()?"I love you my love and our love save us!":"Light my fire!");
    }
    return 0;
}
View Code

1006 Senior Pan

多源多汇最短路,注意在同一个点的情况。

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,long long> pil;
typedef pair<long long,int> pli;
const int maxn=100005;
const long long inf=0x3f3f3f3f3f3f3f3f;
int T,n,m,K,dp[maxn];
bool sta[maxn];
vector<pil> G[maxn];
long long d[maxn];
priority_queue<pli,vector<pli>,greater<pli> > que;
inline long long solve() {
    scanf("%d",&K);
    memset(sta,0,sizeof sta);
    memset(d,0x3f,sizeof d);
    memset(dp,-1,sizeof dp);
    long long res=inf;
    for (int i=0;i<K;++i) {
        int x;
        scanf("%d",&x);
        sta[x]=1;
        que.push(pli(0,x));
        d[x]=0;
        dp[x]=x;
    }
    while (!que.empty()) {
        int u=que.top().second;
        long long td=que.top().first;
        que.pop();
        if (d[u]<td)
            continue;
        for (int i=0;i<(int)G[u].size();++i) {
            int v=G[u][i].first;
            long long o=G[u][i].second;
            if (d[v]>d[u]+o) {
                d[v]=d[u]+o;
                dp[v]=dp[u];
                que.push(pli(d[v],v));
            } else if (d[v]==d[u]+o)
                dp[v]=-1;
            if (sta[v]&&dp[u]!=v)
                res=min(res,d[u]+o);
        }
    }
    return res;
}
int main()
{
    scanf("%d",&T);
    for (int cas=1;cas<=T;++cas) {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;++i)
            G[i].clear();
        for (int i=0;i<m;++i) {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            if (u==v)
                continue;
            G[u].push_back(pil(v,w));
        }
        printf("Case #%d: %I64d
",cas,solve());
    }
    return 0;
}
View Code

1008 Numbers

递推签到

#include <bits/stdc++.h>
const long long mod = 1e9+7;
const double ex = 1e-10;
#define inf 0x3f3f3f3f
using namespace std;
int a[125255];
int c[125255];
map <int,int> M;
int main()
{
    int N;
    while (~scanf("%d",&N)){
        for (int i = 1 ;i<=N; i++)
            scanf("%d",&a[i]);
        M.clear();
        sort(a+1,a+N+1);
        int cnt = 0;
        for (int i = 1; i<=N;i++){
            if (M[a[i]] == 0){
                for (int j = 1; j<=cnt ;j++){
                    M[c[j] + a[i]]++;
                }
                c[++cnt] = a[i];
            }
            else{
                M[a[i]]--;
            }
        }
        printf("%d
",cnt);
        for (int i = 1; i<=cnt ;i++)
            printf("%d%c",c[i],i==cnt?'
':' ');
    }


    return 0;
}
View Code

1010 Two strings

DP 或者 正则表达式

#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;
char s1[2555],s2[2555];
bool dp[2555][2555];
int main()
{
    int T;scanf("%d
",&T);
    while(T--) {
        scanf("%s%s",s1+1,s2+1);
        int len1=strlen(s1+1);int len2=strlen(s2+1);
        for(int i=0;i<=len2;i++) for(int j=0;j<=len1;j++) dp[i][j]=false;
        dp[0][0]=true;
        REP(j,1,len2+1) {
            REP(i,0,len1+1) {
                if(i!=0&&s1[i]==s2[j])
                    dp[j][i]|=(dp[j-1][i-1]&true);
                else if(i!=0&&s2[j]=='.')
                    dp[j][i]|=(dp[j-1][i-1]&true);
                else if(s2[j]=='*') {
                    dp[j][i]|=(dp[j-2][i]);
                    dp[j][i]|=(dp[j-1][i]);
                    dp[j][i]|=(dp[j][i-1]&(s2[j-1]==s1[i]||(s2[j-1]=='.'&&s1[i]==s1[i-1])));
                }
            }
        }
        if(dp[len2][len1]) puts("yes");
        else puts("no");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/myhappinessisall/p/7413472.html