• 2015 ACM/ICPC Asia Regional Changchun Online


    1001 Alisha’s Party

    比赛的时候学长stl吃T。手写堆过。

    赛后我贴了那两份代码都过。相差.2s。

    于是用stl写水果。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 # include <queue>
     5 using namespace std;
     6 # define maxk 151000
     7 int ans[maxk];
     8 
     9 struct node
    10 {
    11     char name[300];
    12     int id,val;
    13     friend bool operator < (node x,node y)
    14     {
    15         if(x.val!=y.val) return x.val<y.val;
    16         return x.id>y.id;
    17     }
    18 } p[maxk];
    19 priority_queue<node> pq;
    20 
    21 struct open
    22 {
    23     int t,p;
    24 } T[maxk];
    25 
    26 bool cmp(open x,open y)
    27 {
    28     return x.t<y.t;
    29 }
    30 
    31 int main(void)
    32 {    
    33     int kase; cin>>kase;
    34     while(kase--)
    35     {
    36         int k,m,q,pos=1,cnt=0,Q;
    37         scanf("%d%d%d",&k,&m,&q);
    38         for(int i=1;i<=k;i++)
    39         {
    40             scanf("%s%d",p[i].name,&p[i].val);
    41             p[i].id=i;
    42         }
    43         for(int i=0;i<m;i++) scanf("%d%d",&T[i].t,&T[i].p);
    44         sort(T,T+m,cmp);
    45         while(!pq.empty()) pq.pop();
    46         for(int i=0;i<m;i++)
    47         {
    48             while(pos<=k&&pos<=T[i].t) pq.push(p[pos++]);
    49             while(!pq.empty()&&T[i].p--)
    50             {
    51                 ans[++cnt]=pq.top().id;
    52                 pq.pop();
    53             }
    54         }
    55         while(pos<=k) pq.push(p[pos++]);
    56         while(!pq.empty())
    57         {
    58             ans[++cnt]=pq.top().id;
    59             pq.pop();
    60         }
    61         for(int i=1;i<q;i++)
    62         {
    63             scanf("%d",&Q);
    64             printf("%s ",p[ans[Q]].name);
    65         }
    66         scanf("%d",&Q);
    67         printf("%s
    ",p[ans[Q]].name);
    68     }
    69     return 0;
    70 }
    Aguin

    1002 Ponds

    赛时题意错理解成对所有奇数联通子集权值求和……

    先dfs或kahn删点。

    再遍历一遍所有奇数联通即可。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cstring>
     4 using namespace std;
     5 typedef long long LL;
     6 const int maxp=10010,maxm=100010;
     7 int cnt,headlist[maxp],v[maxp],deg[maxp];
     8 bool vis[maxp];
     9 LL tmp;
    10 
    11 struct node
    12 {
    13     int to,pre;
    14 } edge[2*maxm];
    15 
    16 void add(int from,int to)
    17 {
    18     cnt++;
    19     edge[cnt].pre=headlist[from];
    20     edge[cnt].to=to;
    21     headlist[from]=cnt;
    22     return;
    23 }
    24 
    25 void dfs1(int pos)
    26 {
    27     deg[pos]=0; vis[pos]=1;
    28     for(int i=headlist[pos];i;i=edge[i].pre)
    29     {
    30         int to=edge[i].to;
    31         if(deg[to]) deg[to]--;
    32         if(deg[to]==1) dfs1(to);
    33     }
    34     return;
    35 }
    36 
    37 int dfs2(int pos)
    38 {
    39     int ret=1;
    40     vis[pos]=1;
    41     tmp+=v[pos];
    42     for(int i=headlist[pos];i;i=edge[i].pre)
    43     {
    44         int to=edge[i].to;
    45         if(vis[to]) continue;
    46         ret+=dfs2(to);
    47     }
    48     return ret;
    49 }
    50 
    51 int main(void)
    52 {
    53     int T; cin>>T;
    54     while(T--)
    55     {
    56         cnt=0;
    57         memset(headlist,0,sizeof(headlist));
    58         memset(deg,0,sizeof(deg));
    59         memset(vis,0,sizeof(vis));
    60         int p,m; scanf("%d%d",&p,&m);
    61         for(int i=1;i<=p;i++) scanf("%d",v+i);
    62         for(int i=0;i<m;i++)
    63         {
    64             int a,b; scanf("%d%d",&a,&b);
    65             add(a,b); add(b,a);
    66             deg[a]++; deg[b]++;
    67         }
    68         for(int i=1;i<=p;i++) if(deg[i]==1) dfs1(i);
    69         LL ans=0;
    70         for(int i=1;i<=p;i++) if(!vis[i]&&deg[i])
    71         {
    72             tmp=0;
    73             if(dfs2(i)%2) ans+=tmp;
    74         }
    75         printf("%I64d
    ",ans);
    76     }
    77     return 0;
    78 }
    Aguin

    1003 Aggregated Counting

    1004 Clock Adjusting

    1005 Travel

    赛场题意理解错。哭。

    询问排序。并查集按秩合并。对答案的贡献是2*r[u]*r[v]。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <algorithm>
     4 using namespace std;
     5 int Ans[5010],pa[21000],r[21000];
     6 
     7 int Find(int x)
     8 {
     9     return pa[x]==x?x:pa[x]=Find(pa[x]);
    10 }
    11 
    12 void Union(int x,int y)
    13 {
    14     x=Find(x),y=Find(y);
    15     if(y<x) swap(x,y);
    16     pa[y]=x; r[x]+=r[y]; 
    17     return;
    18 }
    19 
    20 struct node
    21 {
    22     int from,to,val;
    23     friend bool operator < (node x,node y)
    24     {
    25         return x.val<y.val;
    26     }
    27 } edge[100100];
    28 
    29 struct Query
    30 {
    31     int no,x;
    32     friend bool operator < (Query a,Query b)
    33     {
    34         return a.x<b.x;
    35     }
    36 }query[5010];
    37 
    38 int main(void)
    39 {
    40     int T; cin>>T;
    41     while(T--)
    42     {
    43         int n,m,q; scanf("%d%d%d",&n,&m,&q);
    44         for(int i=1;i<=n;i++){pa[i]=i;r[i]=1;}
    45         for(int i=0;i<m;i++)
    46             scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].val);
    47         sort(edge,edge+m);
    48         for(int i=0;i<q;i++)
    49         {
    50             query[i].no=i;
    51             scanf("%d",&query[i].x);
    52         }
    53         sort(query,query+q);
    54         int pos=0,ans=0;
    55         for(int i=0;i<q;i++)
    56         {
    57             while(pos<m&&edge[pos].val<=query[i].x)
    58             {
    59                 int u=Find(edge[pos].from),v=Find(edge[pos].to);
    60                 pos++;
    61                 if(u==v) continue;
    62                 ans+=2*r[v]*r[u];
    63                 Union(u,v);
    64             }
    65             Ans[query[i].no]=ans;
    66         }
    67         for(int i=0;i<q;i++) printf("%d
    ",Ans[i]);
    68     }
    69     return 0;
    70 }
    Aguin

    1006 Favorite Donut

    讨论这个题目经历了几个阶段。

    比赛时只知道用最大表示法。

    然而由于最大表示法在有多解时返回index最小的。逆时针的处理方法没想好。场上T了。

    赛后想到逆时针多解时必成循环。可以用KMP求循环节。两者都是O(n)。

    后来经过学长提醒。最大表示法如果处理循环串是k增到m后跳出。

    于是可以直接在最大表示法里处理掉循环节。时间上常数优化(并无)。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cstring>
     4 # include <algorithm>
     5 # include <cmath>
     6 using namespace std;
     7 char s[20005];
     8 int m;
     9 
    10 int getMax(int p)
    11 {
    12     int i=0,j=1,k=0;
    13     while(i<m&&j<m&&k<m)
    14     {
    15         int t=s[(i+k)%m]-s[(j+k)%m];
    16         if(!t) k++;
    17         else
    18         {
    19             if(t<0) i=max(i+k+1,j+1);
    20             else j=max(j+k+1,i+1);
    21             k=0;
    22         }
    23     }
    24     if(p&&k==m) return m-1-(m-1-min(i,j))%abs(i-j);
    25     return min(i,j);
    26 }
    27 
    28 int main(void)
    29 {
    30     int T; cin>>T;
    31     while(T--)
    32     {
    33         scanf("%d%s",&m,s);
    34         int op=0,a=getMax(0),b;
    35         reverse(s,s+m);
    36         b=getMax(1);
    37         for(int i=0;i<m;i++)
    38         {
    39             if(s[(2*m-1-a-i)%m]>s[(b+i)%m]) {op=1; break;}
    40             if(s[(2*m-1-a-i)%m]<s[(b+i)%m]) {op=2; break;}
    41         }
    42         if(op==1) printf("%d 0
    ",a+1);
    43         else if(op==2) printf("%d 1
    ",m-b);
    44         else if(a+1<=m-b) printf("%d 0
    ",a+1);
    45         else printf("%d 1
    ",m-b);
    46     }
    47     return 0;
    48 }
    Aguin

    1007 The Water Problem

    水题。ST/线段树/暴力。

     1 # include <iostream>
     2 # include <cstdio>
     3 # include <cmath>
     4 # include <algorithm>
     5 using namespace std;
     6 # define maxn 1000+5
     7 int num[maxn],MAX[maxn][20];
     8 
     9 int main(void)
    10 {
    11     int T; cin>>T;
    12     while(T--)
    13     {
    14         int N,Q; scanf("%d",&N);
    15         for(int i=1;i<=N;i++)
    16         {
    17             scanf("%d",num+i);
    18             MAX[i][0]=num[i];   
    19         }
    20         for(int j=1;j<12;j++)
    21             for(int i=1;i<=N;i++)
    22                 if(i+(1<<j)-1<=N)
    23                     MAX[i][j]=max(MAX[i][j-1],MAX[i+(1<<j-1)][j-1]);
    24         scanf("%d",&Q);
    25         for(int i=0;i<Q;i++)
    26         {
    27             int m,n; scanf("%d%d",&m,&n);
    28             int k=(log(double(n-m+1))/log(2));
    29             int ans=max(MAX[m][k],MAX[n-(1<<k)+1][k]);
    30             printf("%d
    ",ans);
    31         }
    32     }
    33     return 0;
    34 }
    Aguin

    1008 Elven Postman

    1009 Food Problem

    1010 Unknown Treasure

    1011 Good Numbers

    1012 Marisa’s Cake

    1013 Robot Dog

  • 相关阅读:
    js18
    js17
    js16
    js15
    js14
    js13
    js12
    js11
    八月二十三的php
    八月二十二的php
  • 原文地址:https://www.cnblogs.com/Aguin/p/4805592.html
Copyright © 2020-2023  润新知