题意:给你一个树,问你树的路径异或和为1的路径树。
WA了N次,后来dfs换成了另一种方式过了,再后来发现是自己忘记了rk数组,还是不够熟练,理解也不够深,后来换成自己的方式过了, 附上两个代码。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef long long ll;
const int N=30005;
struct node
{
int to,nxt,w;
}edge[N*2];
map<string,int> ma;
int in[N],out[N];
int head[N],cnt,tim,a[N];
pair<int,int> q[N];
void add(int u,int v ,int w)
{
edge[++cnt].to=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt;
}
void dfs(int u,int pre,int w)
{
tim++;
in[u]=tim;
a[tim]=w;
for(int i=head[u];~i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v!=pre)
dfs(v,u,w^edge[i].w);
}
out[u]=tim;
}
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
int sum[N<<2],lazy[N<<2];
void up(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void down(int rt,int l,int r)
{
if(lazy[rt])
{
lazy[rt<<1]^=1;
lazy[rt<<1|1]^=1;
int mid=(l+r)>>1;
sum[rt<<1]=mid-l+1-sum[rt<<1];
sum[rt<<1|1]=r-mid-sum[rt<<1|1];
lazy[rt]=0;
}
}
void build(int l,int r,int rt)
{
lazy[rt]=0;
if(l==r)
{
sum[rt]=a[l];
return;
}
int mid=(l+r)>>1;
build(ls);
build(rs);
up(rt);
}
void update(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
lazy[rt]^=1;
sum[rt]=r-l+1-sum[rt];
return;
}
int mid=(l+r)>>1;
down(rt,l,r);
if(mid>=L) update(L,R,ls);
if(mid<R) update(L,R,rs);
up(rt);
}
int main()
{
// freopen("/Users/wang/Desktop/text专用/in.txt","r",stdin);
// freopen("/Users/wang/Desktop/text专用/out.txt","w",stdout);
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
ma.clear();
memset(head,-1,sizeof(head));
int n; char u[30],v[30];
int w ;cnt=0,tim=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",u);
ma[(string)u]=i;
}
for(int i=1;i<n;i++)
{
scanf("%s%s%d",u,v,&w);
int id1=ma[(string)u],id2=ma[(string)v];
add(id1,id2,w);
add(id2,id1,w);
q[i]=make_pair(id1,id2);
}
dfs(1,0,0);
build(2,n,1);
printf("Case #%d:\n",cas);
int qq;
scanf("%d",&qq);
while(qq--)
{
char cmd[5];
scanf("%s",cmd);
if(cmd[0]=='Q')
printf("%d\n", sum[1]*(n-sum[1])*2);
else if(cmd[0]=='M')
{
int pos;
scanf("%d",&pos);
int uu=q[pos].first,vv=q[pos].second;
if(in[uu]>in[vv]) swap(uu,vv);
update(in[vv],out[vv],2,n,1);
}
}
}
}
//11
//11
//a
//b
//c
//d
//e
//f
//g
//h
//i
//j
//k
//a b 1
//a c 1
//b d 1
//b e 0
//e h 1
//h i 0
//i j 1
//j k 0
//c f 0
//c g 1
//10
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef long long ll;
const int N=30005;
struct node
{
int to,nxt,w;
}edge[N*2];
map<string,int> ma;
int in[N],out[N];
int rk[N];
int head[N],cnt,tim,a[N];
pair<int,int> q[N];
void add(int u,int v ,int w)
{
edge[++cnt].to=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt;
}
void dfs(int u,int pre)
{
tim++;
in[u]=tim;
rk[tim]=u;
for(int i=head[u];~i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v!=pre)
{
a[v]=a[u]^edge[i].w;
dfs(v,u);
}
}
out[u]=tim;
}
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
int sum[N<<2],lazy[N<<2];
void up(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void down(int rt,int l,int r)
{
if(lazy[rt])
{
lazy[rt<<1]^=1;
lazy[rt<<1|1]^=1;
int mid=(l+r)>>1;
sum[rt<<1]=mid-l+1-sum[rt<<1];
sum[rt<<1|1]=r-mid-sum[rt<<1|1];
lazy[rt]=0;
}
}
void build(int l,int r,int rt)
{
lazy[rt]=0;
if(l==r)
{
sum[rt]=a[rk[l]];
return;
}
int mid=(l+r)>>1;
build(ls);
build(rs);
up(rt);
}
void update(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
lazy[rt]^=1;
sum[rt]=r-l+1-sum[rt];
return;
}
int mid=(l+r)>>1;
down(rt,l,r);
if(mid>=L) update(L,R,ls);
if(mid<R) update(L,R,rs);
up(rt);
}
int main()
{
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
ma.clear();
memset(head,-1,sizeof(head));
int n; char u[20],v[20];
int w ;cnt=0,tim=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",u);
ma[(string)u]=i;
}
for(int i=1;i<n;i++)
{
scanf("%s%s%d",u,v,&w);
int id1=ma[(string)u],id2=ma[(string)v];
add(id1,id2,w);
add(id2,id1,w);
q[i]=make_pair(id1,id2);
}
a[1]=0;
dfs(1,0);
build(2,n,1);
for(int i=1;i<n;i++)
{
int uu=q[i].first,vv=q[i].second;
if(in[uu]<in[vv])
q[i].first=vv;
else q[i].first=uu;
}
printf("Case #%d:\n",cas);
int qq;
scanf("%d",&qq);
while(qq--)
{
char cmd[5];
scanf("%s",cmd);
if(cmd[0]=='Q')
printf("%d\n", sum[1]*(n-sum[1])*2);
else if(cmd[0]=='M')
{
int pos;
scanf("%d",&pos);
int uu=q[pos].first;
update(in[uu],out[uu],2,n,1);
}
}
}
}
//11
//11
//a
//b
//c
//d
//e
//f
//g
//h
//i
//j
//k
//a b 1
//a c 1
//b d 1
//b e 0
//e h 1
//h i 0
//i j 1
//j k 0
//c f 0
//c g 1
//10