西安网络赛 xor
2017-09-23 01:06
197 查看
There is a tree with nn nodes.
For each node, there is an integer value a_iai,
(1
\le a_i \le 1,000,000,0001≤ai≤1,000,000,000 for 1
\le i \le n1≤i≤n).
There is qq queries
which are described as follow: Assume the value on the path from node aa to
node bbis t_0,
t_1, \cdots t_mt0,t1,⋯tm.
You are supposed to calculate t_0t0 xor t_ktk xor t_{2k}t2k xor
... xor t_{pk}tpk (pk
\le m)(pk≤m).
n \le 50,000, \sum q \le 500,000)(∑n≤50,000,∑q≤500,000).
For each dataset: In the first n-1n−1 lines,
there are two integers u,vu,v,
indicates there is an edge connect node uu and
node vv.
In the next nn lines,
There is an integer a_iai (1
\le a_i \le 1,000,000,0001≤ai≤1,000,000,000).
In the next qq lines,
There is three integers a,ba,b and kk.
(1
\le a,b,k \le n1≤a,b,k≤n).
让你求 u v上的 第0,k,2k,3k 点的异或和
暴力异或 我的代码要加输入挂。。估计写丑了
#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
vector<int> e
;
int vis
;
int dep
;
int du
;
int f
[20];
int a
;
int xr
;
namespace fastIO
{
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc()
{
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend)
{
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1)
{
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch = nc()));
if(IOerror) return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
#undef BUF_SIZE
};
using namespace fastIO;
void dfs(int u,int v)
{
xr[u]=xr[v]^a[u];
for(int i=0;i<e[u].size();i++)
{
if(e[u][i]==v) continue;
dep[e[u][i]]=dep[u]+1;
f[e[u][i]][0]=u;
dfs(e[u][i],u);
}
}
int n;
void ST()
{
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i<=n;i++)
{
if(f[i][j-1]!=-1)
{
f[i][j]=f[f[i][j-1]][j-1];
}
}
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
int t=dep[x]-dep[y];
for(int i=0;i<=17;i++)
if((1<<i)&t) x=f[x][i];
if(x==y) return x;
for(int i=17;i>=0;i--)
{
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
}
if(x==y) return x;
return f[x][0];
}
int num[30];
int main()
{
int q;
while(read(n),read(q), !IOerror)
{
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++) e[i].clear();
for(int i=1;i<n;i++)
{
int u,v;
read(u),read(v);
e[u].push_back(v);
e[v].push_back(u);
}
for(int i=1;i<=n;i++)
read(a[i]);
dep[1]=1;
dfs(1,0);
ST();
while(q--)
{
int x,y,k;
read(x),read(y),read(k);
if(k==1)
{
int lc=lca(x,y);
printf("%d\n",xr[x]^xr[y]^a[lc] );
continue;
}
vector<int> rr;
int lc=lca(x,y);
int sum=0;
sum^=a[x];
int kk=k,cnt=0;
while(kk)
{
if(kk%2) num[cnt]=1;
else num[cnt]=0;
kk>>=1;
cnt++;
}
while(1)
{
int ww=x;
int flag=0;
for(int i=0;i<cnt;i++)
if(num[i])
ww=f[ww][i];
if(dep[ww]<dep[lc])
break;
x=ww;
sum^=a[x];
}
int len=dep[x]-dep[lc];
int len1=(dep[y]-dep[lc]-(k-len))%k;
if(dep[y]+len1<=dep[lc]||len1<0)
{
printf("%d\n",sum );
continue;
}
for(int i=0;i<=cnt;i++)
if((1<<i)&len1)
y=f[y][i];
sum^=a[y];
while(1)
{
int ww=y;
int flag=0;
for(int i=0;i<cnt;i++)
{
if(num[i])
ww=f[ww][i];
}
if(dep[ww]<=dep[lc]) break;
y=ww;
sum^=a[y];
}
printf("%d\n",sum );
}
}
}
For each node, there is an integer value a_iai,
(1
\le a_i \le 1,000,000,0001≤ai≤1,000,000,000 for 1
\le i \le n1≤i≤n).
There is qq queries
which are described as follow: Assume the value on the path from node aa to
node bbis t_0,
t_1, \cdots t_mt0,t1,⋯tm.
You are supposed to calculate t_0t0 xor t_ktk xor t_{2k}t2k xor
... xor t_{pk}tpk (pk
\le m)(pk≤m).
Input Format
There are multi datasets. (\sumn \le 50,000, \sum q \le 500,000)(∑n≤50,000,∑q≤500,000).
For each dataset: In the first n-1n−1 lines,
there are two integers u,vu,v,
indicates there is an edge connect node uu and
node vv.
In the next nn lines,
There is an integer a_iai (1
\le a_i \le 1,000,000,0001≤ai≤1,000,000,000).
In the next qq lines,
There is three integers a,ba,b and kk.
(1
\le a,b,k \le n1≤a,b,k≤n).
Output Format
For each query, output an integer in one line, without any additional space.样例输入
5 6 1 5 4 1 2 1 3 2 19 26 0 8 17 5 5 1 1 3 2 3 2 1 5 4 2 3 4 4 1 4 5
样例输出
17 19 26 25 019
让你求 u v上的 第0,k,2k,3k 点的异或和
暴力异或 我的代码要加输入挂。。估计写丑了
#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
vector<int> e
;
int vis
;
int dep
;
int du
;
int f
[20];
int a
;
int xr
;
namespace fastIO
{
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc()
{
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend)
{
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1)
{
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch = nc()));
if(IOerror) return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
#undef BUF_SIZE
};
using namespace fastIO;
void dfs(int u,int v)
{
xr[u]=xr[v]^a[u];
for(int i=0;i<e[u].size();i++)
{
if(e[u][i]==v) continue;
dep[e[u][i]]=dep[u]+1;
f[e[u][i]][0]=u;
dfs(e[u][i],u);
}
}
int n;
void ST()
{
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i<=n;i++)
{
if(f[i][j-1]!=-1)
{
f[i][j]=f[f[i][j-1]][j-1];
}
}
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
int t=dep[x]-dep[y];
for(int i=0;i<=17;i++)
if((1<<i)&t) x=f[x][i];
if(x==y) return x;
for(int i=17;i>=0;i--)
{
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
}
if(x==y) return x;
return f[x][0];
}
int num[30];
int main()
{
int q;
while(read(n),read(q), !IOerror)
{
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++) e[i].clear();
for(int i=1;i<n;i++)
{
int u,v;
read(u),read(v);
e[u].push_back(v);
e[v].push_back(u);
}
for(int i=1;i<=n;i++)
read(a[i]);
dep[1]=1;
dfs(1,0);
ST();
while(q--)
{
int x,y,k;
read(x),read(y),read(k);
if(k==1)
{
int lc=lca(x,y);
printf("%d\n",xr[x]^xr[y]^a[lc] );
continue;
}
vector<int> rr;
int lc=lca(x,y);
int sum=0;
sum^=a[x];
int kk=k,cnt=0;
while(kk)
{
if(kk%2) num[cnt]=1;
else num[cnt]=0;
kk>>=1;
cnt++;
}
while(1)
{
int ww=x;
int flag=0;
for(int i=0;i<cnt;i++)
if(num[i])
ww=f[ww][i];
if(dep[ww]<dep[lc])
break;
x=ww;
sum^=a[x];
}
int len=dep[x]-dep[lc];
int len1=(dep[y]-dep[lc]-(k-len))%k;
if(dep[y]+len1<=dep[lc]||len1<0)
{
printf("%d\n",sum );
continue;
}
for(int i=0;i<=cnt;i++)
if((1<<i)&len1)
y=f[y][i];
sum^=a[y];
while(1)
{
int ww=y;
int flag=0;
for(int i=0;i<cnt;i++)
{
if(num[i])
ww=f[ww][i];
}
if(dep[ww]<=dep[lc]) break;
y=ww;
sum^=a[y];
}
printf("%d\n",sum );
}
}
}
相关文章推荐
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Xor
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 xor (根号分治)
- 【分块】计蒜客17120 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G. Xor
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G Xor lca+暴力
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G. Xor
- 2017 ACM西安网络赛 G题 Xor
- 2017 ACM-ICPC西安赛区网络赛 Xor【根号分治、倍增lca】
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G. Xor [LCA+分块]
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Xor
- Coin 2017ICPC西安网络赛
- 2014西安赛区网络赛 5014 Number Sequence
- 2014西安网络预选赛1002(后缀数组求第K大的子串)hdu5008
- HDOJ 5007 Post Robot--2014网络赛西安赛区A题
- HDU 5017 Ellipsoid(西安网络赛K题)
- hdu 5014 Number Sequence(西安网络赛1008)
- 2014西安网络赛1008||hdu5014 二进制
- hdu 5012 Dice(西安网络赛F题,BFS)
- hdu 5017 Ellipsoid 模拟退火算法 西安网络赛
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛: F. Trig Function
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B. Coin