SDOI2017 解题报告

数字表格

\(T\)次询问,每次给出\(n,m(n,m\le 10^6)\)\(f\)为斐波那契数列,\(f_0=0,f_1=1\),求:
\[ \prod _{i=1}^n\prod _{j=1}^mf[gcd(i,j)] \]

题解做法

这个题的思路很妙啊。

看到那个\(gcd\),又注意到前面是个连乘,我们可以构造函数\(g(x)\),使得:
\[ f(x)=\prod _{d|x}g(d) \]
那么:
\[ \begin{aligned} ans&=\prod _{i=1}^n\prod _{j=1}^m\prod _{d|i,d|j}g(d) \\ &=\prod _{d=1}^ng(d)^{\lfloor \frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor} \end{aligned} \]
分段计算即可。

\(g\)的求法很简单:
\[ g(x)=\frac{f(x)}{\prod {_{d|x,d\ne x}g(d)}} \]
预处理复杂度为\(O(n\sqrt n+nlogn)\),询问总复杂度为\(O(Tn(\sqrt n+\sqrt m))\)

想法

其实这个东西如果想不到,还有一个方向可以走:
\[ \begin{aligned} ans&=\prod _{i=1}^n\prod _{j=1}^mf[gcd(i,j)] \\ &=\prod _{d=1}^nf_d^{\prod _{i=1}^{\lfloor\frac{n}{d}\rfloor}\prod _{j=1}^{\lfloor \frac{m}{d}\rfloor}[gcd(i,j)=1]} \\ &=\prod _{d=1}^nf_d^{\prod _{i=1}^{\lfloor\frac{n}{d}\rfloor}\prod _{j=1}^{\lfloor \frac{m}{d}\rfloor}\prod _{k|i,k|j}\mu (k)} \\ &=\prod _{d=1}^nf_d^{\prod _{k=1}^{\lfloor\frac{n}{d}\rfloor}\mu (k)\lfloor\frac{n}{kd}\rfloor\lfloor\frac{m}{kd}\rfloor} \\ 令t&=kd \\ ans&=\prod _{t=1}^n\prod _{k|t}f_k^{\mu (\frac{t}{k})\lfloor\frac{n}{t}\rfloor\lfloor\frac{m}{t}\rfloor} \end{aligned} \]
同样可以分段计算。其实上面的\(g\)就是下面的\[\prod _{k|t}f_k^{\mu (\frac{t}{k})}\]

这就是连乘意义下的莫比乌斯反演:
\[ f(n)=\prod _{d|n}g(d) \Leftrightarrow g(n)=\prod _{d|n}f(d)^{\mu (\frac{n}{d})} \]
两边取对数即得证。

代码

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long giant;
int read() {
    int x=0,f=1;
    char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const int maxn=1e6+1;
const int q=1e9+7;
int f[maxn],g[maxn],iv[maxn],ig[maxn];
int multi(int x,int y) {
    return (giant)x*y%q;
}
int Plus(int x,int y) {
    return ((giant)x+y)%q;
}
int mi(int x,int y) {
    int ret=1;
    for (;y;y>>=1,x=multi(x,x)) if (y&1) ret=multi(ret,x);
    return ret;
}
int inv(int x) {
    return mi(x,q-2);
}
int pre[maxn],ipre[maxn];
int main() {
#ifndef ONLINE_JUDGE
    freopen("test.in","r",stdin);
#endif
    iv[1]=1;
    for (int i=2;i<maxn;++i) iv[i]=q-multi(iv[q%i],q/i);
    f[0]=0,f[1]=g[1]=ig[1]=1;
    for (int i=2;i<maxn;++i) {
        f[i]=Plus(f[i-1],f[i-2]);
        int &in=ig[i]=1;
        for (int j=1;j*j<=i;++j) if (i%j==0) {
            in=multi(in,ig[j]);
            if (j*j!=i) in=multi(in,ig[i/j]);
        }
        g[i]=multi(f[i],in);
        in=inv(g[i]);
    }
    pre[0]=ipre[0]=1;
    for (int i=1;i<maxn;++i) ipre[i]=inv(pre[i]=multi(pre[i-1],g[i]));
    int T=read();
    while (T--) {
        int ret=1,n=read(),m=read();
        if (n>m) swap(n,m);
        for (int l=1,r,c;l<=n;l=r+1) {
            r=min(n/(n/l),m/(m/l));
            int up=(giant)(n/l)%(q-1)*(m/l)%(q-1);
            ret=multi(ret,mi(multi(pre[r],ipre[l-1]),up));
        }
        printf("%d\n",ret);
    }
    return 0;
}

树点涂色

给出一颗\(n\)个点1为根的树,初始时每个点都有个不一样的颜色。我们定义一条路径的权值为路径上不同颜色的个数。有三个操作:

  • 将一个点到根的的路径上的所有点都染成一个新的颜色
  • 询问一条路径\((x,y)\)的权值
  • 询问一个点的子树中所有点,他们到根路径的权值最大的那个

\(n,m\le 10^5\)

分析

这个问题也很巧妙!我们注意到每次操作都修改一个点到根路径上的所有点,每次的颜色都是新的,这就可以发现和link-cut tree的access操作很像。并且有一个性质,由于每次修改都是修改到根的路径,并且都变成新的颜色,所以颜色一定是竖直链状的。这样我们可以想到,如果对每个点维护一个\(f\)值,如果它的颜色与父亲一样,那么这个值为1,否则为0,那么一个点到根路径的权值就是根到这个点路径上的所有点的\(f\)值和,我们称它为\(g\)

我们可以用线段树来维护这个东西,由于询问中有子树询问,所以就使用dfs序的线段树。每次修改用一个access操作,每断掉一条虚边,我们就把这个虚子树的所有点的\(g\)值加1,表示下面的点到根路径上多了一种颜色;每连上一条实边,我们就把这个子树的所有点\(g\)值减1。这样层层往上,我们就可以维护所有点的\(g\)信息了。

询问路径\((x,y)\)的权值,设\(x,y\)\(\text{lca}\)\(l\),那么答案就是\(g_x+g_y-2g_l+1\),想象一下这个情况就知道它减掉两倍\(g_l\)会少掉一种颜色,所以要补回来。

代码

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
int read() {
    int x=0,f=1;
    char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const int maxn=1e5+10;
const int maxj=17;
struct edge {
    int v,nxt;
} e[maxn<<2];
int h[maxn],tot=0;
int f[maxn][maxj],dep[maxn],first[maxn],second[maxn],dft=0,n;
int inv[maxn];
void add(int u,int v) {
    e[++tot]=(edge){v,h[u]};
    h[u]=tot;
}
int lca(int x,int y) {
    if (dep[x]<dep[y]) swap(x,y);
    for (int j=maxj-1;j>=0;--j) if (dep[f[x][j]]>=dep[y]) x=f[x][j];
    if (x==y) return x;
    for (int j=maxj-1;j>=0;--j) if (f[x][j]!=f[y][j]) x=f[x][j],y=f[y][j];
    return f[x][0];
}
struct SGT {
    int t[maxn<<2],tag[maxn<<2];
    void update(int x) {
        t[x]=max(t[x<<1],t[x<<1|1]);
    }
    void build(int x,int l,int r) {
        if (l==r) {
            t[x]=dep[inv[l]];
            tag[x]=0;
            return;
        }
        int mid=l+r>>1;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
        update(x);
    }
    void doit(int x,int d) {
        t[x]+=d;
        tag[x]+=d;
    }
    void pushdown(int x) {
        doit(x<<1,tag[x]);
        doit(x<<1|1,tag[x]);
        update(x);
        tag[x]=0;
    }
    void add(int x,int L,int R,int l,int r,int d) {
        if (L==l && R==r) {
            doit(x,d);
            return;
        }
        int mid=L+R>>1;
        pushdown(x);
        if (r<=mid) add(x<<1,L,mid,l,r,d); else 
        if (l>mid) add(x<<1|1,mid+1,R,l,r,d); else 
        add(x<<1,L,mid,l,mid,d),add(x<<1|1,mid+1,R,mid+1,r,d);
        update(x);
    }
    int query(int x,int L,int R,int l,int r) {
        if (L==l && R==r) return t[x];
        pushdown(x);
        int mid=L+R>>1;
        if (r<=mid) return query(x<<1,L,mid,l,r);
        if (l>mid) return query(x<<1|1,mid+1,R,l,r);
        return max(query(x<<1,L,mid,l,mid),query(x<<1|1,mid+1,R,mid+1,r));
    }
    int one(int p) {
        p=first[p];
        return query(1,1,n,p,p);
    }
} sgt;
struct node {
    int ch[2],fa;
};
struct LCT {
    node t[maxn];
    void link(int x,int y) {
        t[y].fa=x;
    }
    int left(int x) {
        while (t[x].ch[0]) x=t[x].ch[0];
        return x;
    }
    bool isroot(int x) {
        return !x || t[t[x].fa].ch[rson(x)]!=x;
    }
    bool rson(int x) {
        return t[t[x].fa].ch[1]==x;
    }
    void rotate(int x) {
        int f=t[x].fa,d=rson(x),c=t[x].ch[d^1];
        if (!isroot(f)) t[t[f].fa].ch[rson(f)]=x;
int inv[maxn];
        if (c) t[c].fa=f;
        t[x].fa=t[f].fa,t[f].fa=x,t[x].ch[d^1]=f,t[f].ch[d]=c;
    }
    void splay(int x) {
        while (!isroot(x)) {
            if (isroot(t[x].fa)) rotate(x); else {
                if (rson(x)==rson(t[x].fa)) rotate(t[x].fa),rotate(x); else
                rotate(x),rotate(x);
            }
        } 
    }
    void access(int x) {
        for (int last=0;x;x=t[last=x].fa) {
            splay(x);
            int p=t[x].ch[1]?left(t[x].ch[1]):0;
            if (p) sgt.add(1,1,n,first[p],second[p],1);
            t[x].ch[1]=last;
            p=t[x].ch[1]?left(t[x].ch[1]):0;
            if (p) sgt.add(1,1,n,first[p],second[p],-1);
        }
    }
} lct;
void dfs(int x,int fa) {
    inv[first[x]=++dft]=x;
    f[x][0]=fa;
    if (x==fa) dep[x]=1; else dep[x]=dep[fa]+1,lct.link(fa,x);
    for (int i=h[x],v=e[i].v;i;i=e[i].nxt,v=e[i].v) if (v!=fa) dfs(v,x);
    second[x]=dft;
}
int line(int x,int y) {
    int l=lca(x,y);
    int fx=sgt.one(x),fy=sgt.one(y),fl=sgt.one(l);
    return fx+fy-fl-fl+1;
}
int sub(int x) {
    int ret=sgt.query(1,1,n,first[x],second[x]);
    return ret;
} 
int main() {
#ifndef ONLINE_JUDGE
    freopen("test.in","r",stdin);
    freopen("my.out","w",stdout);
#endif
    n=read();
    int m=read();
    for (int i=2;i<=n;++i) {
        int x=read(),y=read();
        add(x,y),add(y,x);
    }
    dfs(1,1);
    for (int j=1;j<maxj;++j) for (int i=1;i<=n;++i) f[i][j]=f[f[i][j-1]][j-1];
    sgt.build(1,1,n);
    while (m--) {
        int op=read();
        if (op==1) {
            int x=read();
            lct.access(x);
        } else if (op==2) {
            int x=read(),y=read();
            int ans=line(x,y);
            printf("%d\n",ans);
        } else if (op==3) {
            int x=read();
            int ans=sub(x);
            printf("%d\n",ans);
        }
    }
    return 0;
}

序列计数

有多少长度为\(n\),其中的数都小于等于\(m\),和模\(p\)为0,且至少含有一个质数的数列?

\(n\le 10^9,m\le 2\times 10^7,p\le 100\)

分析

至少含有一个质数的数列,就是随便乱选的数列个数减去不含质数的数列个数。对于一些可选的数,由于选的次数不限,所以每次我们都可以从当前的选法加上一个数,即\(f_{ij}\)表示选了\(i\)个数,当前模\(p\)\(j\)的方案数,每次通过一个固定的线性转移转移过去。所以可以用矩阵乘法优化解决。我写的是生成函数的方法,本质和矩阵是一样的。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long giant;
const int q=20170408;
int multi(int x,int y) {
    return ((giant)x*y)%q;
}
int Plus(int x,int y) {
    return ((giant)x+y)%q;
}
int sub(int x,int y) {
    return Plus(x,q-y);
}
const int maxn=250;
int a[maxn],b[maxn],n,m,p,c[maxn];
void mul(int a[],int b[]) {
    memset(c,0,sizeof c);
    for (int i=0;i<p;++i) for (int j=0;j<p;++j) c[(i+j)%p]=Plus(c[(i+j)%p],multi(a[i],b[j]));
    for (int i=0;i<p;++i) a[i]=c[i];
}
int first() {
    memset(b,0,sizeof b),b[0]=1;
    memset(a,0,sizeof a);
    for (int i=1;i<=m;++i) ++a[i%p];
    int y=n;
    for (;y;y>>=1,mul(a,a)) if (y&1) 
        mul(b,a);
    return b[0];
}
const int maxm=2e7+1;
const int pss=6e6+1;
bool np[maxm];
int pm[pss],ps=0;
int second() {
    np[1]=true;
    for (int i=2;i<=m;++i) {
        if (!np[i]) pm[++ps]=i;
        for (int j=1;j<=ps && (giant)pm[j]*i<(giant)maxm;++j) {
            int tmp=pm[j]*i;
            np[tmp]=true;
            if (i%pm[j]==0) break;
        }
    }
    memset(b,0,sizeof b),b[0]=1;
    memset(a,0,sizeof a);
    for (int i=1;i<=m;++i) if (np[i]) ++a[i%p];
    int y=n;
    for (;y;y>>=1,mul(a,a)) if (y&1) mul(b,a);
    return b[0];
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("test.in","r",stdin);
#endif
    scanf("%d%d%d",&n,&m,&p);
    int f=first();
    int s=second();
    int ans=sub(f,s);
    printf("%d\n",ans);
}

新生舞会

一个二分图匹配,每一个匹配\((i,j)\)有两个属性\(a_{ij},b_{ij}\),求一个完备匹配,使得:
\[ C=\frac{\sum a_i}{\sum b_i} \]
最大。\(n\le 100\)

分析

二分答案\(C\),我们要求的是是否有一种匹配使得\(\frac{\sum a_i}{\sum b_i}\)大于\(C\),即是否存在一个\(\sum a_i-Cb_i\)大于0的匹配。直接做最大匹配即可,这里用的是KM算法。

代码

#include<cstdio>
#include<cctype>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
int read() {
    int x=0,f=1;
    char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const double eps=1e-10;
const double up=1e8;
const double inf=1e100;
const int maxn=205;
int a[maxn][maxn],b[maxn][maxn],n,match[maxn],pre[maxn];
double f[maxn][maxn],ex[maxn],ey[maxn],slack[maxn];
bool vy[maxn];
void augment(int now) {
    int y;
    fill(slack,slack+n+1,inf);
    memset(vy,0,sizeof vy);
    match[y=0]=now;
    do {
        vy[y]=true;
        int to,x=match[y];
        double d=inf;
        for (int i=1;i<=n;++i) if (!vy[i]) {
            if (ex[x]+ey[i]-f[x][i]<slack[i]) slack[i]=ex[x]+ey[i]-f[x][i],pre[i]=y;
            if (slack[i]<d) d=slack[i],to=i;
        }
        for (int i=0;i<=n;++i) if (vy[i]) ex[match[i]]-=d,ey[i]+=d; else slack[i]-=d;
        y=to;
    } while (match[y]);
    for (;y;y=pre[y]) match[y]=match[pre[y]];
}
double km() {
    for (int i=1;i<=n;++i) 
        augment(i);
    double ret=0;
    for (int i=1;i<=n;++i) ret+=ex[i]+ey[i];
    return ret;
}
bool ok(double c) {
    memset(f,0,sizeof f),memset(ey,0,sizeof ey),memset(match,0,sizeof match),memset(pre,0,sizeof pre);
    for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) f[i][j]=(double)a[i][j]-c*(double)b[i][j];
    for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) ex[i]=(j==1?f[i][j]:max(ex[i],f[i][j]));
    double cost=km();
    return cost>=0;
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("test.in","r",stdin);
    freopen("my.out","w",stdout);
#endif
    n=read();
    for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) a[i][j]=read();
    for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) b[i][j]=read();
    double l=0,r=1e4,mid,ans;
    while (fabs(l-r)>eps) {
        mid=(l+r)/2;
        if (ok(mid)) ans=mid,l=mid; else r=mid;
    }
    printf("%.6lf\n",ans);
    return 0;
}

# 相关分析

230318dba8d63f6a.png

\(n,m\le 10^5\)

分析

这是一个区间修改,区间加法,区间查询奇怪东西的问题,可以看看它要维护的是什么东西,从查询入手。
\[ \begin{aligned} a&=\frac{\sum _{i=L}^R(x_i-\overline x)(y_i-\overline y)}{\sum _{i=L}^R(x_i-\overline x)^2} \\ &=\frac{\sum _{i=L}^Rx_iy_i-\overline x\sum _{i=L}^Ry_i-\overline y\sum _{i=L}^Rx_i+(R-L+1)\overline x\overline y}{\sum _{i=L}^R x_i^2+2\overline x\sum _{i=L}^Rx_i+(R-L+1)\overline x^2} \end{aligned} \]
所以维护区间\(x\)\(y\)\(xy\)\(x^2\)的和就好啦,记得修改的优先级比区间加要高。

代码

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long giant; // remember to change long long 
typedef long double lb;
giant read() {
    giant x=0,f=1;
    char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const giant maxn=1e5+10;
lb basex[maxn],basey[maxn];
int n;
giant pf[maxn];
struct Data {
    /*
     * x is the sum of xi in this range
     * y is the sum of yi in this range
     * xy is the sum of xi*yi in the range
     * fang is the sum of xi*xi in this range
     */
    lb x,y,xy,fang; 
    Data (lb x=0,lb y=0,lb xy=0,lb fang=0):x(x),y(y),xy(xy),fang(fang) {}
    void init(lb _x,lb _y) {
        x=_x,y=_y;
        xy=x*y;
        fang=x*x;
    }
};
Data operator + (Data a,Data b) {
    return Data(a.x+b.x,a.y+b.y,a.xy+b.xy,a.fang+b.fang);
}
Data operator += (Data &a,Data b) {
    a=a+b;
}
struct Tag {
    lb s,t;
    int op;
    Tag (lb s=0,lb t=0,int op=0):s(s),t(t),op(op) {}
    void clear() {
        s=t=op=0;
    }
};
Tag operator + (Tag a,Tag b) {
    return Tag(a.s+b.s,a.t+b.t,max(a.op,b.op));
}
struct SGT {
    Data dat[maxn<<3];
    Tag tag[maxn<<3];
    void build(int x,int l,int r) {
        if (l==r) {
            dat[x].init(basex[l],basey[l]);
            tag[x].clear();
            return;
        }
        giant mid=l+r>>1;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
        dat[x]=dat[x<<1]+dat[x<<1|1];
    }
    void doit(giant x,giant l,giant r,lb s,lb t,int op) {
        if (op==1) {
            Data &d=dat[x];
            d.xy+=t*d.x+s*d.y+(r-l+1)*s*t;
            d.fang+=2*s*d.x+(r-l+1)*s*s;
            d.x+=(r-l+1)*s;
            d.y+=(r-l+1)*t;
            tag[x]=tag[x]+Tag(s,t,op);
        } else if (op==2) {
            Data &d=dat[x];
            giant qj=(l+r)*(r-l+1)/2,f=pf[r]-pf[l-1];
            d.xy=f+qj*(s+t)+(r-l+1)*s*t;
            d.x=qj+(r-l+1)*s;
            d.y=qj+(r-l+1)*t;
            d.fang=f+s*qj*2+(r-l+1)*s*s;
            tag[x]=Tag(s,t,op);
        }
    }
    void pushdown(giant x,giant l,giant mid,giant r) {
        if (tag[x].op==0) return;
        if (tag[x].op==2) {
            doit(x<<1,l,mid,tag[x].s,tag[x].t,tag[x].op);
            doit(x<<1|1,mid+1,r,tag[x].s,tag[x].t,tag[x].op);
        } else if (tag[x].op==1) {
            doit(x<<1,l,mid,tag[x].s,tag[x].t,tag[x].op);
            doit(x<<1|1,mid+1,r,tag[x].s,tag[x].t,tag[x].op);
        }
        tag[x].clear();
    }
    void modify(giant x,giant L,giant R,giant l,giant r,lb s,lb t,int op) {
        giant mid=L+R>>1;
        pushdown(x,L,mid,R);
        if (L==l && R==r) {
            doit(x,L,R,s,t,op);
            return;
        }
        if (r<=mid) modify(x<<1,L,mid,l,r,s,t,op); else
        if (l>mid) modify(x<<1|1,mid+1,R,l,r,s,t,op); else {
            modify(x<<1,L,mid,l,mid,s,t,op);
            modify(x<<1|1,mid+1,R,mid+1,r,s,t,op);
        }
        dat[x]=dat[x<<1]+dat[x<<1|1];
    }
    void modify(giant l,giant r,lb s,lb t,int op) {
        modify(1,1,n,l,r,s,t,op);
    }
    Data query(giant x,giant L,giant R,giant l,giant r) {
        if (L==l && R==r) return dat[x];
        giant mid=L+R>>1;
        pushdown(x,L,mid,R);
        if (r<=mid) return query(x<<1,L,mid,l,r);
        if (l>mid) return query(x<<1|1,mid+1,R,l,r);
        Data r1=query(x<<1,L,mid,l,mid);
        Data r2=query(x<<1|1,mid+1,R,mid+1,r);
        Data ret=r1+r2;
        return ret;
    }
    Data query(giant l,giant r) {
        return query(1,1,n,l,r);
    }
} sgt;
lb calc(int thel,int ther) {
    giant len=ther-thel+1;
    Data d=sgt.query(thel,ther);
    lb up=d.xy,xp=(lb)d.x/len,yp=(lb)d.y/len;
    up-=xp*d.y+yp*d.x;
    up+=len*xp*yp;
    lb down=d.fang;
    down-=2*xp*d.x;
    down+=len*xp*xp;
    lb ret=up/down;
    return ret;
}
void radd(int thel,int ther,lb s,lb t) {
    sgt.modify(thel,ther,s,t,1);
}
void rmodi(int thel,int ther,lb s,lb t) {
    sgt.modify(thel,ther,s,t,2);
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("test.in","r",stdin);
    freopen("my.out","w",stdout);
#endif
    n=read();
    for (int i=1;i<=n;++i) pf[i]=pf[i-1]+(giant)i*i;
    int m=read();
    for (int i=1;i<=n;++i) scanf("%Lf",basex+i);
    for (int i=1;i<=n;++i) scanf("%Lf",basey+i);
    sgt.build(1,1,n);
    while (m--) {
        int op=read();
        if (op==1) {
            int l=read(),r=read();
            lb ans=calc(l,r);
            printf("%.10Lf\n",ans);   // change back to .10lf
        } else if (op==2) {
            int l=read(),r=read();
            lb s,t;
            scanf("%Lf%Lf",&s,&t);
            radd(l,r,s,t);
        } else if (op==3) {
            int l=read(),r=read();
            lb s,t;
            scanf("%Lf%Lf",&s,&t);
            rmodi(l,r,s,t);
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/owenyu/p/6763337.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值