2021-team02-paste
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+1e3+7;
struct Matrix{
int a[3][3];
void init()
{
for(int i=0;i<3;i++)
a[i][i]=1;
}
void clear()
{
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
a[i][j]=0;
}
};
Matrix operator +(const Matrix &A,const Matrix &B)
{
Matrix ret;
ret.clear();
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
ret.a[i][j]=A.a[i][j]+B.a[i][j];
return ret;
}
Matrix operator *(const Matrix &A,const Matrix &B)
{
Matrix ret;
ret.clear();
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
ret.a[i][j]=(ret.a[i][j]+A.a[i][k]*B.a[k][j]);
return ret;
}
struct T{
int l,r,ls,rs;
int tf;
Matrix tag,val;
}t[N*2+1];
void update(int x)
{
t[x].val=t[t[x].ls].val+t[t[x].rs].val;
}
void add(int x,const Matrix &v)
{
t[x].val=t[x].val*v;
t[x].tag=t[x].tag*v;
}
void pushdown(int x)
{
add(t[x].ls,t[x].tag);
add(t[x].rs,t[x].tag);
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
t[x].tag.a[i][j]=(i==j);
}
int cnt;
int dc,rev[N];
Matrix w[N];
int build(int l,int r)
{
int x=++cnt;
t[x].l=l,t[x].r=r;
t[x].tag.clear();
t[x].tag.init();
if(l==r)
{
t[x].val=w[rev[l]];
return x;
}
int mid=(l+r)>>1;
t[x].ls=build(l,mid);
t[x].rs=build(mid+1,r);
update(x);
return x;
}
void change(int x,int l,int r,const Matrix &v)
{
if(l<=t[x].l&&t[x].r<=r)
{
add(x,v);
return;
}
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(l<=mid)
change(t[x].ls,l,r,v);
if(r>mid)
change(t[x].rs,l,r,v);
update(x);
}
Matrix query(int x,int l,int r)
{
if(l<=t[x].l&&t[x].r<=r)
return t[x].val;
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
Matrix ret;
ret.clear();
if(l<=mid)
ret=ret+query(t[x].ls,l,r);
if(r>mid)
ret=ret+query(t[x].rs,l,r);
return ret;
}
int n,Q;
int st[N],ed[N],top[N],sz[N],son[N],fa[N],dep[N];
vector<int>g[N],X[N],Y[N],Z[N];
void dfs1(int x)
{
sz[x]=1;
for(int i=0;i<g[x].size();i++)
{
int v=g[x][i];
if(v==fa[x])
continue;
dep[v]=dep[x]+1;
fa[v]=x;
dfs1(v);
w[v].a[0][0]=X[x][i];
w[v].a[0][1]=Y[x][i];
w[v].a[0][2]=Z[x][i];
sz[x]+=sz[v];
if(sz[v]>sz[son[x]])
son[x]=v;
}
}
void dfs2(int x)
{
st[x]=ed[x]=++dc;
rev[dc]=x;
if(!son[x])
return;
top[son[x]]=top[x];
dfs2(son[x]);
for(auto v:g[x])
{
if(v==fa[x]||v==son[x])
continue;
top[v]=v;
dfs2(v);
}
ed[x]=dc;
}
char op[11];
int getpos(char ch)
{
if(ch=='x')
return 0;
if(ch=='y')
return 1;
return 2;
}
Matrix mod;
Matrix qa,qb;
long double qry(int x,int y)
{
qa.clear(),qb.clear();
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])
{
qa=qa+query(1,st[top[x]],st[x]);
x=fa[top[x]];
}
else
{
qb=qb+query(1,st[top[y]],st[y]);
y=fa[top[y]];
}
}
if(dep[x]>dep[y])
qa=qa+query(1,st[y]+1,st[x]);
else if(dep[y]>dep[x])
qb=qb+query(1,st[x]+1,st[y]);
long double X=0,Y=0,Z=0;
X=qa.a[0][0]-qb.a[0][0];
Y=qa.a[0][1]-qb.a[0][1];
Z=qa.a[0][2]-qb.a[0][2];
return sqrt(X*X+Y*Y+Z*Z);
}
signed main()
{
scanf("%lld%lld",&n,&Q);
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
scanf("%s",op);
int id=getpos(op[0]);
int f=op[1]=='+'?1:-1;
int dlt[3]={0,0,0};
dlt[id]+=f*w;
g[u].push_back(v);
X[u].push_back(dlt[0]);
Y[u].push_back(dlt[1]);
Z[u].push_back(dlt[2]);
g[v].push_back(u);
X[v].push_back(-dlt[0]);
Y[v].push_back(-dlt[1]);
Z[v].push_back(-dlt[2]);
}
dfs1(1);
top[1]=1;
dfs2(1);
build(1,n);
while(Q--)
{
int cop;
scanf("%lld",&cop);
if(cop==1)
{
int x,y,d;
scanf("%lld%lld%s%lld",&x,&y,op,&d);
int pos=getpos(op[0]);
int flag=0;
if(y==fa[x])
{
d=360-d;
swap(x,y);
flag=1;
}
if(d==180)
{
mod.clear();
for(int i=0;i<3;i++)
mod.a[i][i]=(i==pos?1:-1);
if(st[y]+flag<=ed[y])
change(1,st[y]+flag,ed[y],mod);
}
else
{
int p1,p2;
if(pos==0)
p1=1,p2=2;
else if(pos==1)
p1=2,p2=0;
else
p1=0,p2=1;
mod.clear();
mod.a[pos][pos]=1;
if(d==90)
{
mod.a[p1][p2]=1;
mod.a[p2][p1]=-1;
}
else
{
mod.a[p2][p1]=1;
mod.a[p1][p2]=-1;
}
if(st[y]+flag<=ed[y])
change(1,st[y]+flag,ed[y],mod);
}
}
else
{
int x,y;
scanf("%lld%lld",&x,&y);
printf("%.15Lf\n",qry(x,y));
}
}
}
请将/etc/apt/sources.list替换为下述内容:
deb http://mirrors.zju.edu.cn/ubuntu bionic main universe restricted multiverse
deb http://mirrors.zju.edu.cn/ubuntu bionic-security main universe restricted multiverse
deb http://mirrors.zju.edu.cn/ubuntu bionic-updates main universe restricted multiverse
deb http://mirrors.zju.edu.cn/ubuntu bionic-backports main universe restricted multiverse
deb-src http://mirrors.zju.edu.cn/ubuntu bionic main universe restricted multiverse
deb-src http://mirrors.zju.edu.cn/ubuntu bionic-security main universe restricted multiverse
deb-src http://mirrors.zju.edu.cn/ubuntu bionic-updates main universe restricted multiverse
deb-src http://mirrors.zju.edu.cn/ubuntu bionic-backports main universe restricted multiverse
run command:
curl https://dl.zjuqsc.com/linux/qsc.public.key | sudo apt-key add -
curl https://dl.zjuqsc.com/linux/debian/qsc.list | sudo tee /etc/apt/sources.list.d/qsc.list
sudo apt-get update
sudo apt-get install zjunet
#include
using namespace std;
#define int long long
const int N=1e6+1e3+7;
struct Matrix{
int a[3][3];
void init()
{
for(int i=0;i<3;i++)
a[i][i]=1;
}
void clear()
{
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
a[i][j]=0;
}
};
Matrix operator +(const Matrix &A,const Matrix &B)
{
Matrix ret;
ret.clear();
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
ret.a[i][j]=A.a[i][j]+B.a[i][j];
return ret;
}
Matrix operator *(const Matrix &A,const Matrix &B)
{
Matrix ret;
ret.clear();
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
ret.a[i][j]=(ret.a[i][j]+A.a[i][k]*B.a[k][j]);
return ret;
}
struct T{
int l,r,ls,rs;
int tf;
Matrix tag,val;
}t[N*2+1];
void update(int x)
{
t[x].val=t[t[x].ls].val+t[t[x].rs].val;
}
void add(int x,const Matrix &v)
{
t[x].val=t[x].val*v;
t[x].tag=t[x].tag*v;
}
void pushdown(int x)
{
add(t[x].ls,t[x].tag);
add(t[x].rs,t[x].tag);
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
t[x].tag.a[i][j]=(i==j);
}
int cnt;
int dc,rev[N];
Matrix w[N];
int build(int l,int r)
{
int x=++cnt;
t[x].l=l,t[x].r=r;
t[x].tag.clear();
t[x].tag.init();
if(l==r)
{
t[x].val=w[rev[l]];
return x;
}
int mid=(l+r)>>1;
t[x].ls=build(l,mid);
t[x].rs=build(mid+1,r);
update(x);
return x;
}
void change(int x,int l,int r,const Matrix &v)
{
if(l<=t[x].l&&t[x].r<=r)
{
add(x,v);
return;
}
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(l<=mid)
change(t[x].ls,l,r,v);
if(r>mid)
change(t[x].rs,l,r,v);
update(x);
}
Matrix query(int x,int l,int r)
{
if(l<=t[x].l&&t[x].r<=r)
return t[x].val;
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
Matrix ret;
ret.clear();
if(l<=mid)
ret=ret+query(t[x].ls,l,r);
if(r>mid)
ret=ret+query(t[x].rs,l,r);
return ret;
}
int n,Q;
int st[N],ed[N],top[N],sz[N],son[N],fa[N],dep[N];
vector
void dfs1(int x)
{
sz[x]=1;
for(int i=0;i { int v=g[x][i]; if(v==fa[x]) continue; dep[v]=dep[x]+1; fa[v]=x; dfs1(v); w[v].a[0][0]=X[x][i]; w[v].a[0][1]=Y[x][i]; w[v].a[0][2]=Z[x][i]; sz[x]+=sz[v]; if(sz[v]>sz[son[x]]) son[x]=v; } } void dfs2(int x) { st[x]=ed[x]=++dc; rev[dc]=x; if(!son[x]) return; top[son[x]]=top[x]; dfs2(son[x]); for(auto v:g[x]) { if(v==fa[x]||v==son[x]) continue; top[v]=v; dfs2(v); } ed[x]=dc; } char op[11]; int getpos(char ch) { if(ch=='x') return 0; if(ch=='y') return 1; return 2; } Matrix mod; Matrix qa,qb; long double qry(int x,int y) { qa.clear(),qb.clear(); while(top[x]!=top[y]) { if(dep[top[x]]>dep[top[y]]) { qa=qa+query(1,st[top[x]],st[x]); x=fa[top[x]]; } else { qb=qb+query(1,st[top[y]],st[y]); y=fa[top[y]]; } } if(dep[x]>dep[y]) qa=qa+query(1,st[y]+1,st[x]); else if(dep[y]>dep[x]) qb=qb+query(1,st[x]+1,st[y]); long double X=0,Y=0,Z=0; X=qa.a[0][0]-qb.a[0][0]; Y=qa.a[0][1]-qb.a[0][1]; Z=qa.a[0][2]-qb.a[0][2]; return sqrt(X*X+Y*Y+Z*Z); } signed main() { scanf("%lld%lld",&n,&Q); for(int i=1;i { int u,v,w; scanf("%lld%lld%lld",&u,&v,&w); scanf("%s",op); int id=getpos(op[0]); int f=op[1]=='+'?1:-1; int dlt[3]={0,0,0}; dlt[id]+=f*w; g[u].push_back(v); X[u].push_back(dlt[0]); Y[u].push_back(dlt[1]); Z[u].push_back(dlt[2]); g[v].push_back(u); X[v].push_back(-dlt[0]); Y[v].push_back(-dlt[1]); Z[v].push_back(-dlt[2]); } dfs1(1); top[1]=1; dfs2(1); build(1,n); while(Q--) { int cop; scanf("%lld",&cop); if(cop==1) { int x,y,d; scanf("%lld%lld%s%lld",&x,&y,op,&d); int pos=getpos(op[0]); int flag=0; if(y==fa[x]) { d=360-d; swap(x,y); flag=1; } if(d==180) { mod.clear(); for(int i=0;i<3;i++) mod.a[i][i]=(i==pos?1:-1); if(st[y]+flag<=ed[y]) change(1,st[y]+flag,ed[y],mod); } else { int p1,p2; if(pos==0) p1=1,p2=2; else if(pos==1) p1=2,p2=0; else p1=0,p2=1; mod.clear(); mod.a[pos][pos]=1; if(d==90) { mod.a[p1][p2]=1; mod.a[p2][p1]=-1; } else { mod.a[p2][p1]=1; mod.a[p1][p2]=-1; } if(st[y]+flag<=ed[y]) change(1,st[y]+flag,ed[y],mod); } } else { int x,y; scanf("%lld%lld",&x,&y); printf("%.15Lf\n",qry(x,y)); } } } 请将/etc/apt/sources.list替换为下述内容: deb http://mirrors.zju.edu.cn/ubuntu bionic main universe restricted multiverse deb http://mirrors.zju.edu.cn/ubuntu bionic-security main universe restricted multiverse deb http://mirrors.zju.edu.cn/ubuntu bionic-updates main universe restricted multiverse deb http://mirrors.zju.edu.cn/ubuntu bionic-backports main universe restricted multiverse deb-src http://mirrors.zju.edu.cn/ubuntu bionic main universe restricted multiverse deb-src http://mirrors.zju.edu.cn/ubuntu bionic-security main universe restricted multiverse deb-src http://mirrors.zju.edu.cn/ubuntu bionic-updates main universe restricted multiverse deb-src http://mirrors.zju.edu.cn/ubuntu bionic-backports main universe restricted multiverse run command: curl https://dl.zjuqsc.com/linux/qsc.public.key | sudo apt-key add - curl https://dl.zjuqsc.com/linux/debian/qsc.list | sudo tee /etc/apt/sources.list.d/qsc.list sudo apt-get update sudo apt-get install zjunet