zoukankan      html  css  js  c++  java
  • 2017 Multi-University Training Contest

    rank 103/766

    1003 Kanade's sum

    拿链表维护每个数前面比它大的数的位置,乘法原理搞一搞即可。注意链表可以从1开始依次删点,做到O(1)维护每个操作。

    #include <bits/stdc++.h>
    #define maxn 500010
    #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 n,k,a[maxn],pos[maxn],dpL[85],dpR[85];
    int nex[maxn],last[maxn];
    int main()
    {
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d %d",&n,&k);
            for(int j=0;j<=k;j++) dpL[j]=dpR[j]=0;
            REP(i,1,n+1) {
                scanf("%d",&a[i]);
                pos[a[i]]=i;
            }
            for (int i = 1; i<=n; i++) {
                nex[i] = i+1;
                last[i] = i-1;
            }
            ll ans=0;
            for(int i=1;i<=n;i++){
                int now = pos[i];
                int t1 = now;
                int tmp = now;
                for(int j=1;j<=k;++j){
                    tmp=t1;t1 = nex[t1];
                    if(t1==n+1) {dpR[j]=(n-(tmp)+1);break;}
                    else
                        dpR[j]=((t1)-(tmp));
                }
                t1 = now;
                for(int j=1;j<=k;++j){
                    tmp=t1;t1 = last[t1];
                    if(0==t1) {dpL[j]=(tmp);break;}
                    else{
                        dpL[j]=((tmp)-(t1));
                    }
                }
                nex[last[now]] = nex[now];
                last[nex[now]] = last[now];
                for(int j=1;j<=k;++j)
                    ans+=1LL*i*dpL[j]*dpR[k+1-j];
                for(int j=0;j<=k;++j) dpL[j]=dpR[j]=0;
            }
            printf("%I64d
    ",ans);
        }
    }
    View Code

    1005 RXD and dividing

    注意是求最大值。对于每个子树,它的节点个数为Q,将它分成min(Q,K)份,dfs一遍维护答案即可。

    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <iostream>
    using namespace std;
    typedef pair<int,long long> pil;
    typedef pair<long long,int> pli;
    const int maxn=1000005;
    int a,b,n,K;
    long long c,sz[maxn],depth[maxn],res;
    vector<pil> G[maxn];
    priority_queue<pli> que;
    void dfs(int u,int fa,long long dep) {
        depth[u]=dep;
        for (int i=0;i<(int)G[u].size();++i) {
            int v=G[u][i].first;
            if (v==fa)
                continue;
            dfs(v,u,G[u][i].second);
            sz[u]+=sz[v];
        }
        ++sz[u];
        res+=dep*min(1LL*K,sz[u]);
    }
    int main()
    {
        while (scanf("%d%d",&n,&K)==2) {
            memset(sz,0,(n+1)*sizeof sz[0]);
            memset(depth,0,(n+1)*sizeof depth[0]);
            for (int i=0;i<=n;++i)
                G[i].clear();
            for (int i=0;i<n-1;++i) {
                scanf("%d%d%I64d",&a,&b,&c);
                G[a].push_back(pil(b,c));
                G[b].push_back(pil(a,c));
            }
            res=0;
            dfs(1,-1,0);
            cout<<res<<endl;
        }
        return 0;
    }
    View Code

    1008 RXD and math

    打表发现答案就是n^k,快速幂求一下。

    #include <bits/stdc++.h>
    using namespace std;
    int cas;
    const long long mod=1e9+7;
    long long ksm(long long x,long long n) {
        long long ret=1;
        while (n) {
            if (n&1)
                ret=ret*x%mod;
            n>>=1;
            x=x*x%mod;
        }
        return ret;
    }
    int main()
    {
        long long n,k;
        while (scanf("%I64d%I64d",&n,&k)==2) {
            ++cas;
            printf("Case #%d: %I64d
    ",cas,ksm(n%mod,k));
        }
        return 0;
    }
    View Code

    1010 RXD, tree and sequence

    可以把问题转化为 区间相邻LCA最小值

    #include <bits/stdc++.h>
    const long long mod = 1e9+7;
    const double ex = 1e-10;
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,K;
    struct edge{
        int to,nxt;
    }E[355555];
    int deep[355555],head[355555],tot,a[355555],p[355555][30],dp[5][355555];
    void addedge (int x,int y){
        E[tot] = (edge){y,head[x]};
        head[x] = tot++;
    }
    inline void dfs(int u)
    {
      for(int i=head[u];i!=-1;i=E[i].nxt){
        int v = E[i].to;
        if (!deep[v]){
          deep[v] = deep[u]+1;
          p[v][0] = u;
          dfs(v);
        }
      }
    }
    void init()
    {
      int i,j;
      for(j=1;(1<<j)<=n;j++)
        for(i=1;i<=n;i++)
          if(p[i][j-1]!=-1)
            p[i][j]=p[p[i][j-1]][j-1];
    }
    int lca(int a,int b)
    {
      if (a==0||b==0) return 0;
      int i,j;
      if(deep[a]<deep[b])swap(a,b);
      for(i=0;(1<<i)<=deep[a];i++);
      i--;
      for(j=i;j>=0;j--)
        if(deep[a]-(1<<j)>=deep[b])
          a=p[a][j];
      if(a==b)return a;
      for(j=i;j>=0;j--)
      {
        if(p[a][j]!=-1&&p[a][j]!=p[b][j])
        {
          a=p[a][j];
          b=p[b][j];
        }
      }
      return p[a][0];
    }
    int main()
    {
        deep[0] = inf;
        while (scanf("%d%d",&n,&K)==2){
            memset(head,-1,sizeof(head));tot = 0;
            memset(a,0,sizeof(a));
            for (int i = 1 ; i <= n ;i++){
                scanf("%d",&a[i]);
            }
    
            for (int i = 1 ;i < n; i++){
                int x,y;
                scanf("%d%d",&x,&y);
                addedge(x,y);
                addedge(y,x);
            }
            memset(deep,0,sizeof(deep));
            deep[1] = 1;dfs(1);init();
            memset(dp,inf,sizeof(dp));
            dp[0][0] = 0;
            for (int i = 1; i<=n; i++){
                dp[i%3][0] = 0;
    
                for (int j = 1;j <=min(i,K);j++){
                    dp[i%3][j] = min(dp[i%3][j],dp[(i+2)%3][j-1]+deep[a[i]]);
                    if (i>1) dp[i%3][j] = min(dp[i%3][j],dp[(i+2)%3][j]);
                    if (i-2>=0)dp[i%3][j] = min(dp[i%3][j],dp[(i+1)%3][j-1]+deep[lca(a[i],a[i-1])]);
                }
            }
            cout << dp[n%3][K]<<endl;
        }
        return 0;
    }
    1010

    1011 RXD's date

    签到题。输出小于等于35的数的个数。

    #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;
    int t;
    int main()
    {
        while(scanf("%d",&t)!=EOF){
            int cnt=0;
            REP(i,1,t+1) {
                int tmp;scanf("%d",&tmp);
                if(tmp<=35) cnt++;
            }
        printf("%d
    ",cnt);
        }
    }
    View Code
  • 相关阅读:
    存储过程练习 超市管理系统
    SQL 视图
    SQL 存储过程
    SQL 变量、 运算符、 if 、while
    连接查询
    关于表的主外键关系练习 师生 分数表
    java 代码
    转--select/poll/epoll到底是什么一回事
    python学习路线--从入门到入土
    转---变量LEGB规则
  • 原文地址:https://www.cnblogs.com/myhappinessisall/p/7270091.html
Copyright © 2011-2022 走看看