Usaco2012-2013 金组 题解 (暂缺Hill walk以及Figue eight)
https://files.cnblogs.com/files/Winniechen/usaco2012-2013.pdf
做的不是很好,还请见谅!
如果有什么疑问,可以QQ上找我。
QQ号:1967199892
附上代码:
BZOJ3010: [Usaco2012 Dec]Gangs of Istanbull
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <queue> #include <cstdlib> #include <cstring> using namespace std; #define N 105 void Update(int& gang,int& cows,int come) { if(!cows)gang=come; if(gang==come)cows++; else cows--; } int n,m;vector<int > v; int max_cow(int gang,int cows,vector <int>v) { sort(v.begin()+1,v.end()); while(v.back()>0) { for(int i=v.size()-1;i;i--) { Update(gang,cows,i); v[i]--; if(v[i-1]<=v[i])break; } } for(int i=0;i<v[0];i++)Update(gang,cows,0); return gang==0?cows:0; } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int x; scanf("%d",&x); v.push_back(x); } int gang=0,cow=0,ret=max_cow(gang,cow,v); if(ret>0) { printf("YES\n%d\n",ret); for(int i=0;i<n;i++) { int pre_gang=gang,pre_cow=cow; for(int j=0;;j++) { if(!v[j])continue; v[j]--; Update(gang,cow,j); if(max_cow(gang,cow,v)==ret){printf("%d\n",j+1);break;} v[j]++; gang=pre_gang;cow=pre_cow; } } }else { printf("NO\n"); } return 0; }
BZOJ3011: [Usaco2012 Dec]Running Away From the Barn
#include <cstdio> #include <algorithm> #include <iostream> #include <queue> #include <cmath> #include <cstring> #include <cstdlib> using namespace std; #define N 200005 #define ll long long struct node { int dis,ls,rs; ll x; }mp[N]; struct no { int to,next; ll val; }e[N]; int head[N],cnt; void add(int x,int y,ll z) { e[cnt].to=y; e[cnt].val=z; e[cnt].next=head[x]; head[x]=cnt++; return ; } int fa[N],n,siz[N]; ll dep[N],L; int merge(int x,int y) { if(!x)return y; if(!y)return x; if(mp[x].x<mp[y].x)swap(x,y); mp[x].rs=merge(mp[x].rs,y); if(mp[mp[x].rs].dis>mp[mp[x].ls].dis)swap(mp[x].ls,mp[x].rs); mp[x].dis=mp[mp[x].rs].dis+1; return x; } int find(int x) { if(x==fa[x])return x; return fa[x]=find(fa[x]); } void dfs(int x,int from) { siz[x]=1; for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=from) { mp[to1].x=dep[to1]=dep[x]+e[i].val; dfs(to1,x); siz[x]+=siz[to1]; int fx=find(x),fy=find(to1); fa[fx]=fa[fy]=merge(fx,fy); } } int fx=find(x); while(mp[fx].x>L+dep[x]) { fa[fx]=fa[mp[fx].ls]=fa[mp[fx].rs]=merge(mp[fx].ls,mp[fx].rs); siz[x]--; fx=find(x); } return ; } int main() { fa[1]=1; memset(head,-1,sizeof(head)); scanf("%d%lld",&n,&L); for(int i=2;i<=n;i++) { fa[i]=i; int x; ll y; scanf("%d%lld",&x,&y); add(x,i,y); } dfs(1,0); for(int i=1;i<=n;i++) { printf("%d\n",siz[i]); } return 0; }
BZOJ3012: [Usaco2012 Dec]First!
#include <cstdio> #include <algorithm> #include <queue> #include <cstring> #include <cstdlib> #include <cmath> #include <iostream> #include <set> #include <vector> using namespace std; #define N 30005 struct node { int son[27],flag; }a[N*10]; struct no { int to,next; }e[N]; int head[30],cnt,ans[N],in1[N],tot=1,n; char s[N][305]; void add(int x,int y) { e[cnt].to=y; e[cnt].next=head[x]; head[x]=cnt++; in1[y]++; } void insert(int x) { int rt=1; int len=strlen(s[x]); for(int i=0;i<len;i++) { int idx=s[x][i]-'a'+1; if(!a[rt].son[idx])a[rt].son[idx]=++tot; rt=a[rt].son[idx]; } a[rt].flag=1; } bool tsort() { queue <int>q; for(int i=1;i<=26;i++)if(!in1[i])q.push(i); while(!q.empty()) { int x=q.front();q.pop(); for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; in1[to1]--; if(!in1[to1])q.push(to1); } } for(int i=1;i<=26;i++)if(in1[i])return 0; return 1; } bool check(int x) { int rt=1; int len=strlen(s[x]); for(int i=0;i<len;i++) { if(a[rt].flag)return 0; int idx=s[x][i]-'a'+1; for(int j=1;j<=26;j++) { if(j!=idx&&a[rt].son[j])add(idx,j); } rt=a[rt].son[idx]; } return tsort(); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",&s[i]); insert(i); } for(int i=1;i<=n;i++) { memset(head,-1,sizeof(head)); memset(in1,0,sizeof(in1));cnt=0; if(!check(i))continue; ans[++ans[0]]=i; } printf("%d\n",ans[0]); for(int i=1;i<=ans[0];i++) { printf("%s\n",s[ans[i]]); } return 0; }
BZOJ3013: [Usaco2012 Nov]Balanced Cow Breeds
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <queue> #include <cstdlib> #include <cstring> using namespace std; #define N 1005 #define mod 2012 int f[N*2],n,sum; char s[N]; int main() { scanf("%s",s+1);n=strlen(s+1);sum=f[1]=1; for(int i=1;i<=n&&sum>0;i++) { int x=0; if(s[i]=='(')x=1;else x=-1; sum+=x; if(x==-1) { for(int j=1;j<=sum;j++) { f[j]=(f[j-x]+f[j])%mod; } }else { for(int j=sum;j>=1;j--) { f[j]=(f[j-x]+f[j])%mod; } } f[sum+1]=0; } if(sum!=1) { puts("0");return 0; } printf("%d\n",f[1]); return 0; }
BZOJ3014: [Usaco2012 Nov]Balanced Trees
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <cstdlib> #include <queue> #include <iostream> using namespace std; #define N 40005 struct node { int to,next; }e[N<<1]; int head[N],cnt,vis[N],n,ans,f[N],mf[N],g[N],mg[N]; int a[N],siz[N],mx[N],rot,sn,maxx; void add(int x,int y) { e[cnt].to=y; e[cnt].next=head[x]; head[x]=cnt++; } void get_root(int x,int from) { siz[x]=1,mx[x]=0; for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=from&&!vis[to1]) { get_root(to1,x); siz[x]+=siz[to1]; mx[x]=max(mx[x],siz[to1]); } } mx[x]=max(sn-siz[x],mx[x]); if(mx[x]<mx[rot])rot=x; } void get_left(int x,int from,int now,int last,int sum) { siz[x]=1; if(now||a[x]==-1)now-=a[x];else last++;sum=max(sum,now-last); if(!now)f[last]=1,mf[last]=max(mf[last],sum),maxx=max(last,maxx); for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=from&&!vis[to1]) { siz[x]+=siz[to1]; get_left(to1,x,now,last,sum); } } } void get_right(int x,int from,int now,int last,int sum) { siz[x]=1; if(now||a[x]==1)now+=a[x];else last++;sum=max(sum,now-last); if(!now)g[last]=1,mg[last]=max(mg[last],sum),maxx=max(last,maxx); for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=from&&!vis[to1]) { siz[x]+=siz[to1]; get_right(to1,x,now,last,sum); } } } int tms[N]; void calc(int x) { int v=0,maxn=0,tot=0; for(int i=head[x];i!=-1;i=e[i].next) { f[0]=1,mf[0]=0; maxx=0;tms[++tot]=i; int to1=e[i].to; if(!vis[to1]) { get_left(to1,x,0,0,0); for(int k=0;k<=maxx;k++)ans=max(ans,g[k]*f[k]*max(mf[k]+k,mg[k]+k)); for(int k=1;k<=maxx;k++)f[k]=0,mf[k]=0; maxx=0; get_right(to1,x,a[x]==1,a[x]==-1,a[x]==1),maxn=max(maxx,maxn);ans=max(ans,mg[0]); if(a[x]==-1)g[1]=1,mg[1]=max(mg[1],1),maxx=max(maxx,1); } } for(int i=0;i<=maxn;i++)g[i]=0,mg[i]=0;maxn=0; for(int j=tot;j;j--) { int i=tms[j],to1=e[i].to;f[0]=1,mf[0]=0;maxx=0; if(!vis[to1]) { get_left(to1,x,0,0,0); for(int k=0;k<=maxx;k++)ans=max(ans,g[k]*f[k]*max(mf[k]+k,mg[k]+k)); for(int k=1;k<=maxx;k++)f[k]=0,mf[k]=0; maxx=0; get_right(to1,x,a[x]==1,a[x]==-1,a[x]==1),maxn=max(maxx,maxn);ans=max(ans,mg[0]); if(a[x]==-1)g[1]=1,mg[1]=max(mg[1],1),maxx=max(maxx,1); } } for(int i=0;i<=maxn;i++)g[i]=0,mg[i]=0;maxn=0; } void dfs(int x) { //printf("%d\n",x); //printf("%d\n",ans); vis[x]=1;calc(x); for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(!vis[to1]) { rot=0,sn=siz[to1]; get_root(to1,x); dfs(rot); } } } char s[2]; int main() { scanf("%d",&n);memset(head,-1,sizeof(head)); for(int i=2;i<=n;i++) { int x; scanf("%d",&x); add(x,i);add(i,x); } for(int i=1;i<=n;i++) { scanf("%s",s); if(s[0]=='(')a[i]=1; else a[i]=-1; } mx[0]=1<<30;sn=n;rot=0;get_root(1,0);dfs(rot); printf("%d\n",ans); }
BZOJ3015: [Usaco2012 Nov]Concurrently Balanced Strings
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <cstdlib> #include <queue> #include <map> #include <iostream> using namespace std; #define N 50005 int a[10][N],n,k,ans,R[10][N<<1];char s[N]; map<vector<int> ,pair<int ,int > >mp; int main() { scanf("%d%d",&k,&n); for(int i=0;i<k;i++) { scanf("%s",s); for(int j=0;j<n;j++) { if(s[j]=='(')a[i][j]=1; else a[i][j]=-1; } } vector<int>L(k,n); for(int i=0;i<k;i++) { for(int j=0;j<=2*n;j++) { R[i][j]=n; } R[i][n]=0; } mp[L]=make_pair(0,1); for(int i=0;i<n;i++) { int left=0; for(int j=0;j<k;j++) { if(a[j][i]==1)R[j][++L[j]]=i+1; else L[j]--,R[j][L[j]]=min(R[j][L[j]],i+1); left=max(left,R[j][L[j]]); } if(left==n)continue; pair<int ,int >&tmp=mp[L]; if(tmp.first==left)ans+=tmp.second++; else tmp=make_pair(left,1); } printf("%d\n",ans); return 0; }
BZOJ3048: [Usaco2013 Jan]Cow Lineup
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <cstdlib> #include <queue> #include <iostream> using namespace std; #define N 100005 struct node { int x,rnk,idx; }a[N]; int n,k,num[N],ans,tot; bool cmp(const node &a,const node &b){return a.x<b.x;} bool cmp1(const node &a,const node &b){return a.idx<b.idx;} int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++){scanf("%d",&a[i].x);a[i].idx=i;}sort(a+1,a+n+1,cmp); int cnt=0;for(int i=1;i<=n;i++){if(a[i].x!=a[i-1].x)cnt++;a[i].rnk=cnt;}sort(a+1,a+n+1,cmp1); int r=1,l=1;while(tot<=k+1&&r<=n){tot+=(!num[a[r].rnk]);num[a[r].rnk]++;ans=max(ans,num[a[r].rnk]);r++;} for(int i=r;i<=n;i++) { tot+=(!num[a[i].rnk]);num[a[i].rnk]++; while(tot>k+1) { num[a[l].rnk]--; if(!num[a[l].rnk])tot--; l++; } ans=max(num[a[i].rnk],ans); } printf("%d\n",ans); }
BZOJ3049: [Usaco2013 Jan]Island Travels
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <cstdlib> #include <queue> #include <iostream> using namespace std; #define N 55 #define M 1<<15 #define p(i,j) ((i-1)*c+j) int f[16][M],map[N][N],dis[N*N],vis[N*N],n,r,c,head[N*N],cnt,idx[N]; struct node{int to,next,val;}e[N*N*10]; void add(int x,int y,int z){e[cnt].to=y;e[cnt].next=head[x];e[cnt].val=z;head[x]=cnt++;} priority_queue <pair<int ,int > >q; void Dijkstra(int S) { memset(vis,0,sizeof(vis));memset(dis,0x3f,sizeof(dis)); while(!q.empty())q.pop();q.push(make_pair(0,S));dis[S]=0; while(!q.empty()) { int x=q.top().second;q.pop(); if(vis[x])continue; vis[x]=1; for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(dis[to1]>dis[x]+e[i].val) { dis[to1]=dis[x]+e[i].val; q.push(make_pair(-dis[to1],to1)); } } } return ; } char s[N][N];int dx[4]={0,1,-1,0},dy[4]={1,0,0,-1}; void dfs(int x,int y,int cnt) { for(int i=0;i<4;++i) { int xx=x+dx[i]; int yy=y+dy[i]; if(xx<1||xx>r||yy<1||yy>c||s[xx][yy]!='X'||map[xx][yy])continue; map[xx][yy]=cnt; dfs(xx,yy,cnt); } } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&r,&c); for(int i=1;i<=r;i++) { scanf("%s",s[i]+1); } for(int i=1;i<=r;i++) { for(int j=1;j<=c;j++) { if(s[i][j]=='X') { if(!map[i][j])map[i][j]=++n,idx[n]=p(i,j),dfs(i,j,n); } else if(s[i][j]=='S')map[i][j]=0; else map[i][j]=-1; } } for(int i=1;i<=r;i++) { for(int j=1;j<=c;j++) { if(map[i][j]==-1)continue; if(j!=c&&map[i][j+1]!=-1)add(p(i,j),p(i,j+1),!map[i][j+1]),add(p(i,j+1),p(i,j),!map[i][j]); if(i!=r&&map[i+1][j]!=-1)add(p(i,j),p(i+1,j),!map[i+1][j]),add(p(i+1,j),p(i,j),!map[i][j]); } } memset(map,0x3f,sizeof(map));memset(f,0x3f,sizeof(f)); for(int i=1;i<=n;i++) { f[i][1<<(i-1)]=0;Dijkstra(idx[i]); for(int j=1;j<=n;j++) { map[i][j]=dis[idx[j]]; } } for(int S=1;S<(1<<n);S++) { for(int i=1;i<=n;i++) { if(!(S&(1<<i-1)))continue; for(int j=1;j<=n;j++) { if(!(S&(1<<j-1)))continue; int s=S^(1<<i-1); f[i][S]=min(f[j][s]+map[j][i],f[i][S]); } } } int ans=1<<30; for(int i=1;i<=n;i++)ans=min(ans,f[i][(1<<n)-1]); printf("%d\n",ans); return 0; }
BZOJ3050: [Usaco2013 Jan]Seating
#include <cstdio> #include <cmath> #include <cstring> #include <iostream> #include <queue> #include <algorithm> using namespace std; #define N 500005 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int sum[N<<2],lsum[N<<2],rsum[N<<2],cover[N<<2]; int n,Q; void PushUp(int m,int rt) { lsum[rt]=lsum[rt<<1]; rsum[rt]=rsum[rt<<1|1]; if(lsum[rt]==(m-(m>>1)))lsum[rt]+=lsum[rt<<1|1]; if(rsum[rt]==(m>>1))rsum[rt]+=rsum[rt<<1]; sum[rt]=max(max(sum[rt<<1],sum[rt<<1|1]),lsum[rt<<1|1]+rsum[rt<<1]); return ; } void PushDown(int l,int rt) { if(cover[rt]!=-1) { cover[rt<<1]=cover[rt<<1|1]=cover[rt]; rsum[rt<<1]=lsum[rt<<1]=sum[rt<<1]=cover[rt]*(l-(l>>1)); rsum[rt<<1|1]=lsum[rt<<1|1]=sum[rt<<1|1]=cover[rt]*(l>>1); cover[rt]=-1; } return ; } void build(int l,int r,int rt) { cover[rt]=-1; if(l==r) { rsum[rt]=lsum[rt]=sum[rt]=1; return ; } int m=(l+r)>>1; build(lson); build(rson); PushUp(r-l+1,rt); return ; } void Update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { rsum[rt]=c*(r-l+1); lsum[rt]=c*(r-l+1); sum[rt]=c*(r-l+1); cover[rt]=c; return ; } PushDown(r-l+1,rt); int m=(l+r)>>1; if(m>=L)Update(L,R,c,lson); if(m<R)Update(L,R,c,rson); PushUp(r-l+1,rt); return ; } int query(int x,int l,int r,int rt) { if(l==r)return l; PushDown(r-l+1,rt); int m=(l+r)>>1; if(sum[rt<<1]>=x) { return query(x,lson); }else if(lsum[rt<<1|1]+rsum[rt<<1]>=x) { return m-rsum[rt<<1]+1; }else { return query(x,rson); } } int read() { int x=0; char c=getchar(); while(c<'0'||c>'9')c=getchar(); while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+(c-'0'); c=getchar(); } return x; } char s[10]; int main() { n=read(),Q=read(); build(1,n,1); int ans=0; while(Q--) { int x,y; scanf("%s",s); x=read(); if(s[0]=='A') { if(sum[1]<x) { ans++; }else { int p=query(x,1,n,1); Update(p,p+x-1,0,1,n,1); } }else { y=read(); Update(x,y,1,1,n,1); } } printf("%d\n",ans); return 0; }
BZOJ3062: [Usaco2013 Feb]Taxi
#include <cstdio> #include <algorithm> #include <cmath> #include <cstdlib> #include <cstring> #include <queue> #include <iostream> using namespace std; #define N 100005 int a[N],b[N],n,m;long long ans; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i],&b[i]);ans+=abs(b[i]-a[i]); } a[n+1]=m,b[n+1]=0; sort(a+1,a+n+2);sort(b+1,b+n+2); for(int i=1;i<=n+1;i++)ans+=abs(b[i]-a[i]); printf("%lld\n",ans); return 0; }
BZOJ3063: [Usaco2013]Route Designing
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <queue> using namespace std; #define N 100005 #define ll long long struct node { int x,y; friend bool operator<(const node &a,const node &b) { if(a.x==b.x)return a.y<b.y; return a.x<b.x; } }e[N]; ll f[N],g[N],a[N],b[N]; int n,m,r; int main() { scanf("%d%d%d",&n,&m,&r); for(int i=1;i<=n;i++)scanf("%lld",&a[i]),f[i]=a[i]; for(int i=1;i<=m;i++)scanf("%lld",&b[i]),g[i]=b[i]; for(int i=1;i<=r;i++)scanf("%d%d",&e[i].x,&e[i].y); sort(e+1,e+r+1); for(int i=1;i<=r;i++) { int x=e[i].x,y=e[i].y; ll t=f[x]; f[x]=max(g[y]+a[x],f[x]); g[y]=max(t+b[y],g[y]); } ll ans=0; for(int i=1;i<=n;i++)ans=max(ans,f[i]); for(int i=1;i<=m;i++)ans=max(ans,g[i]); printf("%lld\n",ans); }
BZOJ3074: [Usaco2013 Mar]The Cow Run
#include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib> #include <cstring> #include <queue> #include <iostream> #include <set> using namespace std; #define N 1005 long long f[N][N],g[N][N]; int n,a[N]; int main() { memset(f,0x3f,sizeof(f));memset(g,0x3f,sizeof(g)); scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); sort(a+1,a+n+1); int p=lower_bound(a+1,a+n+1,0)-a; if(p!=1)f[p-1][1]=g[p-1][1]=1ll*n*(0-a[p-1]); if(a[p]>=0)f[p][1]=g[p][1]=1ll*n*(a[p]-0); for(int i=2;i<=n;i++) { for(int j=1;j<=n-i+1;j++) { int k=i+j-1; f[j][i]=min(f[j+1][i-1]+(n-i+1)*(a[j+1]-a[j]),g[j+1][i-1]+(n-i+1)*(a[k]-a[j])); g[j][i]=min(f[j][i-1]+(a[k]-a[j])*(n-i+1),g[j][i-1]+(a[k]-a[k-1])*(n-i+1)); } } printf("%lld\n",min(f[1][n],g[1][n])); return 0; }
BZOJ3075: [Usaco2013]Necklace
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <queue> using namespace std; #define N 10005 char str[N],sub[N]; int nxt[N],f[N][1005],n,m; void get_next() { int j=0;nxt[1]=0; for(int i=2;i<=m;i++) { while(sub[j+1]!=sub[i]&&j)j=nxt[j]; nxt[i]=(sub[j+1]==sub[i])?++j:0; } } int main() { memset(f,0x3f,sizeof(f)); scanf("%s%s",str+1,sub+1);n=strlen(str+1),m=strlen(sub+1);get_next(); f[0][0]=0; for(int i=1;i<=n;i++) { for(int j=0;j<m;j++)if(f[i-1][j]!=0x3f3f3f3f) { f[i][j]=min(f[i][j],f[i-1][j]+1); int k=j; while(k&&str[i]!=sub[k+1])k=nxt[k]; if(sub[k+1]==str[i])k++; f[i][k]=min(f[i][k],f[i-1][j]); } } int ans=1<<30; for(int i=0;i<m;i++)ans=min(ans,f[n][i]); printf("%d\n",ans); }
BZOJ3126: [Usaco2013 Open]Photo
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <cstdlib> #include <queue> #include <iostream> using namespace std; #define N 200005 int l1[N],r1[N],n,m,f[N],q[N]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n+1;i++)r1[i]=i-1; for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); l1[y+1]=max(x,l1[y+1]);r1[y]=min(x-1,r1[y]); } for(int i=n;i>=1;i--)r1[i]=min(r1[i+1],r1[i]); for(int i=2;i<=n+1;i++)l1[i]=max(l1[i],l1[i-1]); int h=0,t=0,j=1; for(int i=1;i<=n+1;i++) { while(j<=r1[i]&&j<=n) { if(f[j]==-1){j++;continue;} while(f[j]>f[q[t]]&&h<=t)t--; q[++t]=j;j++; } while(l1[i]>q[h]&&h<=t)h++; if(h<=t)f[i]=f[q[t]]+(i!=n+1); else f[i]=-1; } printf("%d\n",f[n+1]); return 0; }
BZOJ3127: [Usaco2013 Open]Yin and Yang
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <queue> #include <cstring> #include <cstdlib> using namespace std; #define N 100005 #define ll long long int siz[N],mx[N],head[N],cnt,tot,sn,rot,vis[N],n,len; struct node { int to,next,val; }e[N<<1]; ll ans,f[N][2],g[N][2]; void add(int x,int y,int z) { e[cnt].to=y; e[cnt].val=z; e[cnt].next=head[x]; head[x]=cnt++; } void get_root(int x,int from) { siz[x]=1;mx[x]=0; for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=from&&!vis[to1]) { get_root(to1,x); siz[x]+=siz[to1]; mx[x]=max(mx[x],siz[to1]); } } mx[x]=max(mx[x],sn-siz[x]); if(mx[rot]>mx[x])rot=x; } void calc(int x,int from,int now,int cnt) { if(now==0) { if(cnt>=2)ans++; cnt++; } for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(to1!=from&&!vis[to1]) { calc(to1,x,now+e[i].val,cnt); } } } void get_dep(int x,int from,int now,int l,int r) { if(l<=now&&now<=r) { if(now>=0)f[now][1]++; else g[-now][1]++; }else { if(now>=0)f[now][0]++; else g[-now][0]++; } l=min(l,now);r=max(r,now);len=max(max(r,-l),len); for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(!vis[to1]&&to1!=from) { get_dep(to1,x,now+e[i].val,l,r); } } } void dfs(int x) { vis[x]=1;calc(x,0,0,0); get_dep(x,0,0,1,-1),ans+=f[0][1]*(f[0][1]-1)/2;f[0][0]=f[0][1]=0; for(int i=1;i<=len;i++)ans+=f[i][0]*g[i][1]+g[i][0]*f[i][1]+f[i][1]*g[i][1],f[i][0]=f[i][1]=g[i][1]=g[i][0]=0; for(int i=head[x];i!=-1;i=e[i].next) { int to1=e[i].to; if(!vis[to1]) { len=0;get_dep(to1,0,e[i].val,0,0);ans-=f[0][1]*(f[0][1]-1)/2;f[0][1]=f[0][0]=0; for(int i=0;i<=len;i++)ans-=f[i][0]*g[i][1]+g[i][0]*f[i][1]+f[i][1]*g[i][1],f[i][0]=f[i][1]=g[i][1]=g[i][0]=0; sn=siz[to1]; rot=0;get_root(to1,0); dfs(rot); } } } int main() { memset(head,-1,sizeof(head)); scanf("%d",&n); for(int i=1;i<n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z*2-1); add(y,x,z*2-1); } sn=n;mx[0]=n; get_root(1,0); dfs(rot); printf("%lld\n",ans); return 0; }