【THUWC2017】在美妙的数学王国中畅游

题面

https://www.luogu.org/problem/P4546

题解

泰勒展开一般函数转多项式,$LCT$维护多项式。

#include<cmath>
#include<stack>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ri register int
#define N 120000
using namespace std;

const double e=pow(2,1/log(2));
char typ[15];
int n,m,f[N],ch[N][2],ff[N],rev[N];
double ts[N][15],a[N],b[N];
stack<int> s;

bool notroot(int x) {
  return ch[ff[x]][0]==x || ch[ff[x]][1]==x;
}
bool opt(int x) {
  return ch[ff[x]][1]==x;
}

void pushup(int x) {
  if (f[x]==1) {
    ts[x][0]=sin(a[x]*0.5+b[x]);
    ts[x][1]=cos(a[x]*0.5+b[x])*a[x];
    for (ri i=2;i<15;i++) ts[x][i]=ts[x][i-2]*(-a[x]*a[x]);
  }
  else if (f[x]==2) {
    ts[x][0]=pow(e,0.5*a[x]+b[x]);
    for (ri i=1;i<15;i++) ts[x][i]=ts[x][i-1]*a[x];
  }
  else if (f[x]==3) {
    ts[x][0]=0.5*a[x]+b[x];
    ts[x][1]=a[x];
    for (ri i=2;i<15;i++) ts[x][i]=0;
  }
  for (ri i=0;i<15;i++) ts[x][i]+=ts[ch[x][0]][i]+ts[ch[x][1]][i];
}

void pushdown(int x) {
  if (!rev[x]) return;
  rev[x]=0;
  swap(ch[x][0],ch[x][1]);
  rev[ch[x][0]]^=1; rev[ch[x][1]]^=1;
}

void rotate(int x) {
  int y=ff[x],z=ff[y],s=opt(x),w=ch[x][1^s];
  ff[x]=z; if (notroot(y)) ch[z][opt(y)]=x;
  ch[y][s]=w; ff[w]=y;
  ff[y]=x; ch[x][1^s]=y;
  pushup(y); pushup(x);
}

void splay(int x) {
  int tx=x;
  while (1) {
    s.push(tx);
    if (!notroot(tx)) break;
    tx=ff[tx];
  }
  while (!s.empty()) pushdown(s.top()),s.pop();
  while (notroot(x)) {
    if (!notroot(ff[x])) {
      rotate(x);
    }
    else {
      if (opt(x)==opt(ff[x])) rotate(ff[x]),rotate(x);
      else rotate(x),rotate(x);
    }
  }
}

void access(int x) {
  int y=0;
  while (x) {
    splay(x);
    ch[x][1]=y; pushup(x);
    y=x; x=ff[x];
  }
}

void makeroot(int x) {
  access(x); splay(x);
  rev[x]^=1;
}

void split(int x,int y) {
  makeroot(x);
  access(y); splay(y);
}

void cut(int x,int y) {
  split(x,y);
  ff[x]=ch[y][0]=0;
  pushup(y);
}

void link(int x,int y) {
  makeroot(x);
  ff[x]=y;
}

int findroot(int x) {
  access(x); splay(x);
  while (ch[x][0]) x=ch[x][0];
  return x;
}

int main() {
  scanf("%d %d %s",&n,&m,typ);
  for (ri i=1;i<=n;i++) scanf("%d %lf %lf",&f[i],&a[i],&b[i]);
  char ch[20];
  for (ri i=1,u,v;i<=m;i++) {
    scanf("%s",ch);
    if (ch[0]=='a') {
      scanf("%d %d",&u,&v);
      u++; v++;
      link(u,v);
    }
    else if (ch[0]=='d') {
      scanf("%d %d",&u,&v);
      u++; v++;
      cut(u,v);
    }
    else if (ch[0]=='m') {
      scanf("%d",&u);
      u++;
      splay(u);
      scanf("%d %lf %lf",&f[u],&a[u],&b[u]);
      pushup(u);
    }
    else {
      double T;
      scanf("%d %d %lf",&u,&v,&T);
      u++; v++;
      if (findroot(u)!=findroot(v)) {
        puts("unreachable");
      }
      else {
        double ans=0;
        split(u,v);
        double p1=1,p2=1;
        for (ri i=0;i<15;i++) ans+=ts[v][i]*p2/p1,p1*=(i+1),p2*=(T-0.5);
        printf("%.8e\n",ans);
      }
    }
  }
  return 0;
}

 

posted @ 2019-09-06 23:24  HellPix  阅读(210)  评论(0编辑  收藏  举报