2017 Multi-University Training Contest - Team 9
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?'\n':' '); } } 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 , " \n"[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, " \n"[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; }
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\n",cas,solve()); } return 0; }
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\n",cnt); for (int i = 1; i<=cnt ;i++) printf("%d%c",c[i],i==cnt?'\n':' '); } return 0; }
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\n",&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; }