今天满课啊,天气太冷了,网上找了一下虚树的东西,还没弄懂~~~(;´д`)ゞ
牛客网挑战赛1
给定一棵n个点的树,问其中有多少条长度为偶数的路径。路径的长度为经过的边的条数。x到y与y到x被视为同一条路径。路径的起点与终点不能相同。
输入描述:
第一行一个数n表示点的个数;
接下来n-1行,每行两个整数x,y表示边;
保证输入数据形成一棵树;
1<=n<=100000
输出描述:
一行一个整数表示答案。
示例1
输入
3 1 2 1 3
输出
1
分析:奇数层到奇数层,偶数层到偶数层。
题目描述
给定一个长度为n的整数数组,问有多少对互不重叠的非空区间,使得两个区间内的数的异或和为0。
输入描述:
第一行一个数n表示数组长度;
第二行n个整数表示数组;
1<=n<=1000,0<=数组元素<100000。
输出描述:
一行一个整数表示答案。
示例1
输入
3 0 0 0
输出
5
说明
([1,1],[2,2]),([1,1],[3,3]),([1,1],[2,3]),([1,2],[3,3]),([2,2],[3,3])
又是一道异或题,涨姿势了~~~
网上有很多二分的方案,有一种很巧妙的遍历方式。
枚举中心轴,右区间做测试,左区间维护异或值。遍历左区间,从右到左记录~~~
#include <bits/stdc++.h> using namespace std; const int maxn = 1e3+5; int a[maxn]; int sets[3276800]; int main() { //freopen("in.txt","r",stdin); int n; cin>>n; for(int i = 1; i <= n; i++) scanf("%d",&a[i]); long long cnt = 0; for(int i = 1; i <= n; i++) { int s = 0; for(int j = i; j <=n; j++) { s^=a[j]; cnt+=sets[s]; } s = 0; for(int j = i; j >= 1; j--) { s^=a[j]; sets[s]++; } } printf("%lld ",cnt); return 0; }