codeforces ABBYY Cup 2.0
B
RMQ+LCA+边双连通
View Code
#include<string.h> #include<stdio.h> #include<vector> #include<math.h> using namespace std; const int M =100100; const double inf = 1e20; inline int min(int a,int b){return a<b?a:b;} int tdfn,tot; int dp[20][2*M],vis[M]; int B[2*M],LOG[2*M],used[M],F[2*M],pos[M]; int Btype,Time,dfn[M],low[M],Belong[M],st[M],Top; vector<int> newe[2*M]; vector<pair<int,int> >rec; void rmq_init(int n,int num[]) { int i,j; for(j=1;j<=n;j++) dp[0][j]=num[j]; for(j=1;j<=LOG[n];j++) { int limit=n+1-(1<<j); for(i=1;i<=limit;i++) { int x=i+(1<<j>>1); dp[j][i]=min(dp[j-1][x],dp[j-1][i]); } } } int rmq(int l,int r,int num[]) { int m=LOG[r-l+1]; return min(dp[m][l],dp[m][r-(1<<m)+1]); } int sum[M]; void lca_dfs(int s) { int i,t; used[s]=1; int tmp=++tdfn; B[++tot]=tmp;F[tmp]=s; pos[s]=tot; for(i=0;i<newe[s].size();i++) { t=newe[s][i]; if(used[t]) continue; sum[t]=sum[s]+1; lca_dfs(t); B[++tot]=tmp;//backtrack } } int lca(int a,int b) { if(pos[a]>pos[b]) swap(a,b); int ans=rmq(pos[a],pos[b],B); return F[ans]; } struct Edge { int s,t; int next; int vis; }edge[1000005]; int head[M]; int E; void add_edge(int s,int t) { edge[E].s=s; edge[E].t=t; edge[E].vis=0; edge[E].next=head[s]; head[s]=E++; } void dfs(int s) { int i,t,id; st[++Top]=s; dfn[s]=low[s]=++Time; for (i=head[s];i!=-1;i=edge[i].next) { if(edge[i].vis)continue; edge[i].vis=edge[i^1].vis=1; t=edge[i].t; if (!dfn[t]) { dfs(t); low[s]=min(low[s],low[t]); } else low[s]=min(low[s],dfn[t]); if(low[t]>dfn[s]) { // printf("s=%d t=%d\n",s,t); rec.push_back(make_pair(s,t)); } } if(dfn[s]==low[s]) { Btype++; do{ t=st[Top--]; Belong[t]=Btype; }while(t!=s); } } void SCC(int n) { int i; Time=0;Btype=0;Top=0; memset(dfn,0,sizeof(int)*(n+1)); for(i=1;i<=n;i++)if(!dfn[i]) dfs(i); } int main() { int i,n,m,a,b,w,k; LOG[0]=-1; for(i=1;i<2*M;i++) LOG[i]=LOG[i>>1]+1; while(scanf("%d%d",&n,&m)!=EOF) { E=0; memset(head,-1,sizeof(head)); for(i=0;i<m;i++) { scanf("%d%d",&a,&b); add_edge(a,b); add_edge(b,a); } SCC(n); for(i=0;i<=Btype;i++) newe[i].clear(); for(i=0;i<rec.size();i++) { newe[Belong[rec[i].first]].push_back(Belong[rec[i].second]); newe[Belong[rec[i].second]].push_back(Belong[rec[i].first]); } sum[1]=0;tdfn=0;tot=0;memset(used,0,sizeof(used)); lca_dfs(1); rmq_init(tot,B); scanf("%d",&k); while(k--) { scanf("%d%d",&a,&b); int aa=Belong[a],bb=Belong[b]; printf("%d\n",sum[aa]+sum[bb]-2*sum[lca(aa,bb)]); } } return 0; }
C题:
codeforces题目链接http://codeforces.com/contest/178/problem/C3
各种stl,各种没用过。。。
于是果断学习了,自己写了一下,调试什么的也还算顺利
View Code
#pragma warning (disable:4786) #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <map> #include <set> using namespace std; const int maxn = 200010; int h,m,n; int vis[maxn],seq[maxn],rank[maxn]; set<int> a[maxn]; map<int,pair<int,int> > history; void release(pair<int,int> p){ a[p.first].insert(p.second); } int main() { int i,r=0,id,hash; __int64 ans=0; scanf("%d%d%d",&h,&m,&n); for(i=0;i<h;i++) if(!vis[i]) { for(int c=0,j=i;!vis[j];j=(j+m)%h,c++) { rank[j]=r; seq[j]=c; a[r].insert(c); vis[j]=1; } r++; }char s[5]; while(n--) { scanf("%s%d",s,&id); if(s[0]=='-') release(history[id]); else { scanf("%d",&hash); int A=rank[hash],B=seq[hash]; set<int> ::iterator it=a[A].lower_bound(B); if(it==a[A].end()) { it=a[A].begin(); ans+=h/r-B+*it; } else ans+=*it-B; history[id]=make_pair(A,*it);//要先映射再删除,不然it就为空了 a[A].erase(it); } } printf("%I64d\n",ans); return 0; }
f1
两种暴力方法
dfs
View Code
#include<cstdio> #include<cstring> char str[30][510]; int len[50]; int dis[30][30],path[30]; int ans=0,k,n; void dfs(int a,int b,int res) { if(b==k) { if(res>ans) ans=res; return ; } if(a==n) return ; for(int i=a;i<n;i++) { int s=res; for(int j=0;j<b;j++) s+=dis[path[j]][i]; path[b]=i; dfs(i+1,b+1,s); } } int main() { int i,j,m,s; while(scanf("%d%d",&n,&k)!=EOF) { for(i=0;i<n;i++) { scanf("%s",str[i]); len[i]=strlen(str[i]); } for(i=0;i<n;i++) { for(j=i+1;j<n;j++) { for(s=0;s<len[i]&&s<len[j];s++) if(str[i][s]!=str[j][s]) break; dis[i][j]=dis[j][i]=s; } } dfs(0,0,0); printf("%d\n",ans); } return 0; }
状态压缩
View Code
#include<cstdio> #include<cstring> char str[30][510]; int len[50]; int dis[30][30]; int main() { int n,k,i,j,m,s; while(scanf("%d%d",&n,&k)!=EOF) { for(i=0;i<n;i++) { scanf("%s",str[i]); len[i]=strlen(str[i]); } for(i=0;i<n;i++) { for(j=i+1;j<n;j++) { for(s=0;s<len[i]&&s<len[j];s++) if(str[i][s]!=str[j][s]) break; dis[i][j]=dis[j][i]=s; } } int ans=0; for(i=0;i<(1<<n);i++) { for(j=0,m=0;j<n;m+=(i>>j)&1,j++); if(m!=k) continue; for(m=0,j=0;j<n;j++) if((i>>j)&1) for(int x=j+1;x<n;x++) if((i>>x)&1) m+=dis[j][x]; if(m>ans) ans=m; } printf("%d\n",ans); } return 0; }