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

    1001 Travel with candy

    1002 The sum of gcd

    学了莫队补的。基本还是别人的方法。

    先预处理出每个点左右的gcd区间。最多log(a[i])个。

    然后套莫队转移。

      1 # include <iostream>
      2 # include <cstdio>
      3 # include <vector>
      4 # include <algorithm>
      5 # include <cmath>
      6 using namespace std;
      7 typedef long long LL;
      8 const int maxn=10000+10;
      9 int n,Q,block,a[maxn];
     10 LL ans[maxn];
     11 
     12 struct node
     13 {
     14     int no,l,r,gcd;
     15 } query[maxn];
     16 vector <node> Lgcd[maxn],Rgcd[maxn];
     17 
     18 bool cmp(node a,node b)
     19 {
     20     if(a.l/block!=b.l/block) return a.l/block<b.l/block;
     21     return a.r<b.r;
     22 }
     23 
     24 int gcd(int a,int b)
     25 {
     26     return a%b?gcd(b,a%b):b;
     27 }
     28 
     29 void Init(void)
     30 {
     31     scanf("%d",&n);
     32     for(int i=1;i<=n;i++)
     33     {
     34         scanf("%d",a+i);
     35         Lgcd[i].clear();
     36         Rgcd[i].clear();
     37     }
     38     scanf("%d",&Q);
     39     for(int i=1;i<=Q;i++)
     40     {
     41         scanf("%d%d",&query[i].l,&query[i].r);
     42         query[i].no=i;
     43     }
     44     block=sqrt(n);
     45     sort(query+1,query+1+Q,cmp);
     46     return;
     47 }
     48 
     49 void PrePro(void)
     50 {
     51     for(int i=1;i<=n;i++)
     52     {
     53         int pos=i,tem_gcd=a[i];
     54         for(int j=0;j<Lgcd[i-1].size();j++)
     55         {
     56             node tem=Lgcd[i-1][j];
     57             int t=gcd(tem.gcd,tem_gcd);
     58             if(t!=tem_gcd)Lgcd[i].push_back(node{0,pos,0,tem_gcd});
     59             pos=tem.l,tem_gcd=t;
     60         }
     61         Lgcd[i].push_back(node{0,pos,0,tem_gcd});
     62     }
     63     Rgcd[n+1].clear();
     64     for(int i=n;i>=1;i--)
     65     {
     66         int pos=i,tem_gcd=a[i];
     67         for(int j=0;j<Rgcd[i+1].size();j++)
     68         {
     69             node tem=Rgcd[i+1][j];
     70             int t=gcd(tem.gcd,tem_gcd);
     71             if(t!=tem_gcd)Rgcd[i].push_back(node{0,0,pos,tem_gcd});
     72             pos=tem.r,tem_gcd=t;
     73         }
     74         Rgcd[i].push_back(node{0,0,pos,tem_gcd});
     75     }
     76     return;
     77 }
     78 
     79 void Solve(void)
     80 {
     81     LL res=0;
     82     int l=1,r=0;
     83     for(int i=1;i<=Q;i++)
     84     {    
     85         while(r<query[i].r)
     86         {
     87             int pos=++r;
     88             for(int j=0;j<Lgcd[r].size();j++)
     89             {
     90                 node tem=Lgcd[r][j];
     91                 if(tem.l>=l){res+=(LL)(pos-tem.l+1)*(LL)tem.gcd; pos=tem.l-1;}
     92                 else {res+=(LL)(pos-l+1)*(LL)tem.gcd; break;}
     93             }
     94         }
     95         for(;r>query[i].r;r--)
     96         {
     97             int pos=r;
     98             for(int j=0;j<Lgcd[r].size();j++)
     99             {
    100                 node tem=Lgcd[r][j];
    101                 if(tem.l>=l){res-=(LL)(pos-tem.l+1)*(LL)tem.gcd; pos=tem.l-1;}
    102                 else {res-=(LL)(pos-l+1)*(LL)tem.gcd; break;}
    103             }
    104         }
    105         while(l>query[i].l)
    106         {
    107             int pos=--l;
    108             for(int j=0;j<Rgcd[l].size();j++)
    109             {
    110                 node tem=Rgcd[l][j];
    111                 if(tem.r<=r){res+=(LL)(tem.r-pos+1)*(LL)tem.gcd; pos=tem.r+1;}
    112                 else {res+=(LL)(r-pos+1)*(LL)tem.gcd; break;}
    113             }
    114         }
    115         for(;l<query[i].l;l++)
    116         {
    117             int pos=l;
    118             for(int j=0;j<Rgcd[l].size();j++)
    119             {
    120                 node tem=Rgcd[l][j];
    121                 if(tem.r<=r){res-=(LL)(tem.r-pos+1)*(LL)tem.gcd; pos=tem.r+1;}
    122                 else {res-=(LL)(r-pos+1)*(LL)tem.gcd; break;}
    123             }            
    124         }
    125         ans[query[i].no]=res;
    126     }
    127     return;
    128 }
    129 
    130 int main(void)
    131 {
    132     int T; cin>>T;
    133     while(T--)
    134     {
    135         Init();
    136         PrePro();
    137         Solve();
    138         for(int i=1;i<=Q;i++) printf("%I64d
    ",ans[i]);
    139     }
    140     return 0;
    141 }
    Aguin

    1003 GCD?LCM!

    1004 Yu-Gi-Oh!

    1005 Danganronpa

    1006 The path

    从1一开始往大的数BFS。搜到没路为止。

    dis就是以1间隔递增。

    再从n反向搜回来。一样操作。

    因为保证有解。所以两遍一定搜完所有点。

    对于所有u到v的边。如果dis[u]>dis[v]那么这条边肯定不走。置为最大值n即可。

    否则把边置为dis[v]-dis[u]就符合要求了。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cstring>
     4 using namespace std;
     5 # define maxn 100100
     6 int cnt,headlist[maxn],dis[maxn];
     7 
     8 struct node
     9 {
    10     int to,pre,val;
    11 } edge[maxn];
    12 
    13 void add(int from,int to)
    14 {
    15     cnt++;
    16     edge[cnt].pre=headlist[from];
    17     edge[cnt].to=to;
    18     headlist[from]=cnt;
    19 }
    20 
    21 int main(void)
    22 {
    23     int T; cin>>T;
    24     while(T--)
    25     {
    26         cnt=0;
    27         memset(headlist,0,sizeof(headlist));
    28         memset(dis,-1,sizeof(dis));
    29         int n,m; scanf("%d%d",&n,&m);
    30         for(int i=1;i<=m;i++)
    31         {
    32             int u,v;
    33             scanf("%d%d",&u,&v);
    34             add(u,v);
    35         }
    36         dis[1]=0;
    37         int l=1,r=n,pos;
    38         for(int i=1;i<=n;i++)
    39         {
    40             if(dis[l]>=0) pos=l++;
    41             else pos=r--;
    42             dis[pos]=i;
    43             for(int j=headlist[pos];j;j=edge[j].pre)
    44             {
    45                 int to=edge[j].to;
    46                 if(dis[to]>=0) continue;
    47                 dis[to]=0;
    48             }
    49         }
    50         for(int i=1;i<=n;i++)
    51             for(int j=headlist[i];j;j=edge[j].pre)
    52                 edge[j].val=dis[edge[j].to]>dis[i]?dis[edge[j].to]-dis[i]:n;
    53         for(int i=1;i<=m;i++) printf("%d
    ",edge[i].val);
    54     }
    55     return 0;
    56 }
    Aguin

    1007 Cover

    只要不是那么暴力的暴力应该就- -。

     1 # include <iostream>
     2 # include <cstdio>
     3 using namespace std;
     4 int map[101][101],ans[501];
     5 
     6 struct node
     7 {
     8     int type,num,col,used;
     9 } op[501];
    10 
    11 int main(void)
    12 {
    13     int T; cin>>T;
    14     while(T--)
    15     {
    16         int n,m; scanf("%d%d",&n,&m);
    17         for(int t=0;t<2;t++)
    18             for(int i=1;i<=n;i++)
    19                 for(int j=1;j<=n;j++)
    20                     scanf("%d",&map[i][j]);
    21         for(int i=1;i<=m;i++)
    22         {
    23             char s[5];
    24             scanf("%s",s);
    25             if(s[0]=='L') op[i].type=0;
    26             else op[i].type=1;
    27             scanf("%d%d",&op[i].num,&op[i].col);
    28             op[i].used=0;
    29         }
    30         int cnt=m;
    31         while(cnt)
    32         {
    33             for(int i=1;i<=m;i++)
    34             {
    35                 if(!op[i].used)
    36                 {
    37                     int ok=1;
    38                     if(op[i].type)
    39                     {
    40                         int x=op[i].num,c=op[i].col;
    41                         for(int j=1;j<=n;j++) 
    42                             if(map[x][j]&&map[x][j]!=c)
    43                                 {ok=0;break;}
    44                         if(ok)
    45                         {
    46                             op[i].used=1;
    47                             ans[cnt--]=i;
    48                             for(int j=1;j<=n;j++) map[x][j]=0;
    49                             for(int j=1;j<=m;j++)
    50                                 if(op[j].type&&!op[j].used&&op[j].num==x)
    51                                 {
    52                                     op[j].used=1;
    53                                     ans[cnt--]=j;
    54                                 }
    55                         }
    56                     }
    57                     else
    58                     {
    59                         int x=op[i].num,c=op[i].col;
    60                         for(int j=1;j<=n;j++) 
    61                             if(map[j][x]&&map[j][x]!=c)
    62                                 {ok=0;break;}
    63                         if(ok)
    64                         {
    65                             op[i].used=1;
    66                             ans[cnt--]=i;
    67                             for(int j=1;j<=n;j++) map[j][x]=0;
    68                             for(int j=1;j<=m;j++)
    69                                 if(!op[j].type&&!op[j].used&&op[j].num==x)
    70                                 {
    71                                     op[j].used=1;
    72                                     ans[cnt--]=j;
    73                                 }
    74                         }
    75                     }    
    76                 }
    77             }
    78         }
    79         for(int i=1;i<=m;i++) printf("%d ",ans[i]);
    80         puts("");
    81     }
    82     return 0;
    83 }
    Aguin

    1008 Clock

    枚举所有时刻指针夹角即可。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 using namespace std;
     5 
     6 struct node
     7 {
     8     int h,m,s,a1,a2,b1,b2,c1,c2;
     9 } Time[44000];
    10 
    11 void ans_print(int h,int m,int s)
    12 {
    13     int index=3600*h+60*m+s;
    14     if(Time[index].a2==1) printf("%d ",Time[index].a1);
    15     else printf("%d/%d ",Time[index].a1,Time[index].a2);
    16     if(Time[index].b2==1) printf("%d ",Time[index].b1);
    17     else printf("%d/%d ",Time[index].b1,Time[index].b2);
    18     if(Time[index].c2==1) printf("%d ",Time[index].c1);
    19     else printf("%d/%d ",Time[index].c1,Time[index].c2);
    20     printf("
    ");
    21     return;
    22 }
    23 
    24 void Init(void)
    25 {
    26     for(int h=0;h<12;h++)
    27     {
    28         for(int m=0;m<60;m++)
    29         {
    30             for(int s=0;s<60;s++)
    31             {
    32                 int index=3600*h+60*m+s;
    33     
    34                 int as=s*720;
    35                 int am=720*m+12*s;
    36                 int ah=3600*h+60*m+s;
    37 
    38                 int a1=max(ah,am)-min(ah,am);
    39                 if(a1>21600) a1=43200-a1;
    40                 int a2=120;
    41                 while(a1%2==0&&a2%2==0){a1/=2;a2/=2;}
    42                 while(a1%3==0&&a2%3==0){a1/=3;a2/=3;}
    43                 while(a1%5==0&&a2%5==0){a1/=5;a2/=5;}
    44 
    45                 int b1=max(ah,as)-min(ah,as);
    46                 if(b1>21600) b1=43200-b1;
    47                 int b2=120;
    48                 while(b1%2==0&&b2%2==0){b1/=2;b2/=2;}
    49                 while(b1%3==0&&b2%3==0){b1/=3;b2/=3;}
    50                 while(b1%5==0&&b2%5==0){b1/=5;b2/=5;}
    51 
    52                 int c1=max(as,am)-min(as,am);
    53                 if(c1>21600) c1=43200-c1;
    54                 int c2=120;
    55                 while(c1%2==0&&c2%2==0){c1/=2;c2/=2;}
    56                 while(c1%3==0&&c2%3==0){c1/=3;c2/=3;}
    57                 while(c1%5==0&&c2%5==0){c1/=5;c2/=5;}
    58 
    59                 Time[index].h=h;
    60                 Time[index].m=m;
    61                 Time[index].s=s;
    62                 Time[index].a1=a1;
    63                 Time[index].a2=a2;
    64                 Time[index].b1=b1;
    65                 Time[index].b2=b2;
    66                 Time[index].c1=c1;
    67                 Time[index].c2=c2;
    68             }
    69         }
    70     }
    71     return;
    72 }
    73 
    74 int main(void)
    75 {
    76     Init();
    77     int T ;cin>>T;
    78     while(T--)
    79     {
    80         int h,m,s;
    81         scanf("%d",&h);
    82         if(h>=12) h-=12;
    83         getchar();
    84         scanf("%d",&m);
    85         getchar();
    86         scanf("%d",&s);
    87         ans_print(h,m,s);
    88     }
    89     return 0;
    90 }
    Aguin

    1009 Geometer's Sketchpad

    1010 Zero Escape

    dp题。

    定义状态:dp[i][j]为前i个人中选至少一个人(取的人数小于等于i即可)。使得dr=j的情况数。

    转移:dp[i][j]=dp[i-1][(j-num+8)%9+1]+dp[i-1][j],dp[i][num]++。

    i-1个人(j-num+8)%9+1的情况加上第i个num正好凑成j。再加上不选择第i个人的情况。最后再考虑只取第i个人的情况。

    对9取模后。如果sum等于A+B的话。说明可以组合成两道门都走的情况。

    但是这里注意前面dp定义的是至少选一个人的情况。如果B=sum。就存在全部走B不走A的情况。

    所以答案是dp[n][A]+(B==sum)或者dp[n][B]+(A==sum)也一样。

    如果sum不等于A+B。那么最多选择一扇门走完。

    判断能否走A。能否走B。即可。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 using namespace std;
     5 typedef long long LL;
     6 const int maxn=101000;
     7 const LL mod=258280327;
     8 LL dp[maxn][10];
     9 
    10 int main(void)
    11 {
    12     int T; cin>>T;
    13     while(T--)
    14     {
    15         int n,A,B,num;
    16         scanf("%d%d%d",&n,&A,&B);
    17         int sum=0;
    18         for(int i=1;i<=n;i++)
    19         {
    20             scanf("%d",&num);
    21             sum+=num;
    22             for(int j=1;j<=9;j++) dp[i][j]=(dp[i-1][(j-num+8)%9+1]+dp[i-1][j])%mod;
    23             dp[i][num]=(dp[i][num]+(LL)1)%mod;
    24         }
    25         sum=(sum-1)%9+1;
    26         if(sum==(A+B-1)%9+1) printf("%I64d
    ",(dp[n][A]+(LL)(B==sum))%mod);
    27         else printf("%d
    ",(sum==A)+(sum==B));
    28     }
    29     return 0;
    30 }
    Aguin

    1011 tree

  • 相关阅读:
    Quartz使用总结
    ubuntu 16.04 下载源
    samba搭建
    搭建FTP服务器
    ubuntu 快捷图标
    mysql Fatal error encountered during command execution
    vs2013调试的时候卡顿
    javascript父窗口与子窗口通信
    mysql设置字体
    前台声明变量
  • 原文地址:https://www.cnblogs.com/Aguin/p/4728698.html
Copyright © 2011-2022 走看看