http://codeforces.com/contest/842/problem/C
树上每个点都有一个权值,求每一个点到根节点路径上所有节点的最大公因子,可以删掉任意一个点,也可以不删
删掉一个点影响的只是这个点的所有孩子节点,所有枚举每个点被删掉的情况,这样复杂度是n^2,加一些剪枝,
1.当到根节点的路径上的最大公因子已经是1,则没必要继续向下搜索了
2.当删掉这个点后得到的gcd等于不删这个节点的gcd,则没必要枚举删掉这个点的情况
#include<bits/stdc++.h>
#define eps 1e-9
#define PI 3.141592653589793
#define bs 1000000007
#define bsize 256
#define MEM(a) memset(a,0,sizeof(a))
typedef long long ll;
using namespace std;
int n;
int a[200005];
vector<int>w[200005];
int t[200005],ans[200005];
void dfs1(int x,int fa)
{
if(t[x]>ans[x])
ans[x]=t[x];
for(int i=0;i<w[x].size();i++)
{
if(w[x][i]==fa)
continue;
int temp=__gcd(a[w[x][i]],t[x]);
if(temp==1)
continue;
t[w[x][i]]=temp;
dfs1(w[x][i],x);
}
}
void dfs(int x,int fa)
{
if(t[x]>ans[x])
ans[x]=t[x];
if(t[x]==1)
return ;
for(int i=0;i<w[x].size();i++)
{
if(w[x][i]==fa)
continue;
int temp=__gcd(t[x],a[w[x][i]]);
if(temp!=t[x])
{
t[w[x][i]]=t[x];
dfs1(w[x][i],x);
}
t[w[x][i]]=temp;
dfs(w[x][i],x);
}
}
int main()
{
int i,x,y;
cin>>n;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
ans[i]=1;
}
for(i=1;i<n;i++)
{
scanf("%d %d",&x,&y);
w[x].push_back(y);
w[y].push_back(x);
}
w[0].push_back(1);
dfs(0,0);
for(i=1;i<=n;i++)
printf("%d ",ans[i]);
cout<<endl;
return 0;
}
http://codeforces.com/contest/842/problem/D
数列里有n个数,m次操作,每次给x,让n个数都异或上x。并输出数列的mex值
01trie,相当于按位记录,顶点是最高位,要找异或最大,则向此位数值相反的结点走,要求异或最小,则向此位数值相同的结点走
#include<bits/stdc++.h>
using namespace std;
const int maxn=500005;
int s[30];
struct node
{
int l,r,x;
}seg[maxn*4];
void build(int l,int r,int node)
{
seg[node].l=l;
seg[node].r=r;
if(l==r)
{
return ;
}
int mid=(l+r)>>1;
build(l,mid,node<<1);
build(mid+1,r,node<<1|1);
return ;
}
void update(int node,int k)
{
if(seg[node].l==seg[node].r)
{
seg[node].x=1;
return ;
}
int mid=(seg[node].l+seg[node].r)>>1;
if(mid>=k)
update(node<<1,k);
else
update(node<<1|1,k);
seg[node].x=seg[node<<1].x+seg[node<<1|1].x;
return ;
}
int query(int node,int k)
{
if(seg[node].l==seg[node].r)
{
return 0;
}
int temp=node<<1|s[k];
if(seg[temp].x==seg[temp].r-seg[temp].l+1)
{
return query(temp^1,k-1)+(1<<k);
}
else
{
return query(temp,k-1);
}
}
int main()
{
int n,m,i,j,a;
cin>>n>>m;
build(0,524287,1);
for(i=1;i<=n;i++)
{
scanf("%d",&a);
update(1,a);
}
int now=0;
while(m--)
{
scanf("%d",&a);
now^=a;
for(i=0;i<19;i++)
{
s[i]=(now&(1<<i))==(1<<i);
}
printf("%d\n",query(1,18));
}
return 0;
}