首先我們可以發現g=
(x∗ϕ
)∗1=
(ϕ∗1
)∗x=
x∗x 所以 g(
n)=n
∗d0(
n)其中 d0
(n) 表示
n 的約數個數
然後就是樹上的問題了
我們知道叉乘不滿足結合律 打完之後才知道 汗 但是滿足反交換律
然後我們就可以把叉乘表示成矩陣的形式 這是有結合律的
然後就是卡常歷程 最後幾乎就是照著claris打了
#include
#include
#include
#include
#include
#define cl(x) memset(x,0,sizeof(x))
using
namespace
std;
typedef
long
long ll;
inline
char nc()
inline
void read(int &x)
inline
void write(int x)
const
int p=1000000007;
inline ll pow(ll a,int b)
inline ll inv(ll a)
namespace fg
}} int q[maxn+5]; ll sum=1;
inline
void add(int i,int j)
inline
void add(int n,int r)
if (y!=1) add(back[y],r);
}}const
int n=100005;
struct edgeg[n<<1];
int head[n],inum;
inline
void add(int u,int v,int p)
#define v g[p].v
struct mat
friend mat operator * (mat a,mat b)
void read(int *x)
};inline
void mul(mat &a,mat &b,mat &c)
int n,m;
int val[n],_val[n];
int size[n];
int a[n][3]; mat val[n];
inline
void pdfs(int u,int fa)
mat a[n],b[n],c;
int ans[n][3];
int del[n];
int sum,minv,rt;
inline
void root(int u,int fa)
vector
vec[n];
int _u[n],_v[n];
int _rt[n];
inline
void divide(int u)
for (int i=0;i<(int)vec[u].size();i++)else
} for (int p=head[u];p;p=g[p].next)
if (!del[v])
divide(_rt[v]);
}int main()
divide(rt);
// for (int i=1;i<=m;i++) printf("%d %d %d\n",ans[i][0],ans[i][1],ans[i][2]);
for (int i=1;i<=m;i++) write(ans[i][0]),putchar(' '),write(ans[i][1]),putchar(' '),write(ans[i][2]),putchar('\n');
//printf("%d\n",ncnt);
//for (int i=1;i<=n;i++)
// printf("%d\n",_cnt[i]);
return
0;}
BZOJ3784 樹上的路徑 點分治序 ST表
點分治序就是每次點分治時的dfs序拼起來。點分治序的長度應該是nlogn的。然後對於每一條路徑 u,v 在出現了u的分治結構中,v總是在點分治序的一段區間裡,就可以同noi2010超級鋼琴一樣維護了,就是從堆中取出最大值,並把所在區間再分成兩部分扔進堆裡,重複m次即可。複雜度o nlog 2n in...
動態點分治 bzoj 3730,bzoj 1095
總結一下動態點分治的模板。對於乙個樹,把它點分的同時記錄每個點的所有父親 logn個 並記錄點距其父親的距離。具體實現就是dfs的時候fa x dep x u,dis x dep x d bzoj1095 您需要寫乙個程式支援反轉點的顏色,求距離最遠的黑色點對的距離。解析 在每個點u存乙個堆st記錄...
BZOJ 2599 Race 點的分治
題意 給一棵樹,每條邊有權.求一條路徑,權值和等於k,且邊的數量最小.我會告訴你這就是題面?bzoj的題就是好啊!一句話題意,贊乙個。這道題的思路還是點分治 類似於前面那篇文章裡的兩題,只不過轉換成了求最小而不是計數,每次找好重心u後,我們只考慮以u為根的子樹,u的子樹可以分治下去搞。我們只考慮經過...