Ztxz16学图论

题目大意

给定一张图,每次询问编号在[l,r]的边连上后会形成多少联通块。

离线做法

我们考虑莫队。
考虑左端点所在的每一块,左端点到块末最多根号的距离,右端点是单调的。并查集容易添加,因此只保留块末到右端点的联通情况,每次暴力加上块末到左端点部分。

在线做法

把加入1~i条边,每条边权值设置为编号,所形成的最大生成树叫第i个版本。
[l,r]的答案=第r个版本中联通块数量+第r个版本中[1,l-1]存在树中的数量
依次加上每条边,用LCT维护得到每个版本,然后得到其联通块数量。可持久化线段树来保存每个版本中边的出现情况。

#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
const int maxn=200000+10,maxtot=8000000+10;
int father[maxn*2],key[maxn*2],num[maxn*2],tree[maxn*2][2],pp[maxn*2];
bool bz[maxn*2];
int ans[maxn],root[maxn],left[maxtot],right[maxtot],sum[maxtot],fa[maxn],edge[maxn][2],sta[maxn*2];
int i,j,k,l,r,t,n,m,q,tot,top,cnt,now;
int read(){
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0'||ch>'9'){
        if (ch=='-') f=-1;
        ch=getchar();
    }
    while (ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int getfa(int x){
    return fa[x]?fa[x]=getfa(fa[x]):x;
}
int pd(int x){
    return tree[father[x]][1]==x;
}
void update(int x){
    num[x]=x;
    if (tree[x][0])
        if (key[num[tree[x][0]]]<key[num[x]]) num[x]=num[tree[x][0]];
    if (tree[x][1])
        if (key[num[tree[x][1]]]<key[num[x]]) num[x]=num[tree[x][1]];
}
void rotate(int x){
    int y=father[x],z=pd(x);
    father[x]=father[y];
    if (father[y]) tree[father[y]][pd(y)]=x;
    tree[y][z]=tree[x][1-z];
    if (tree[x][1-z]) father[tree[x][1-z]]=y;
    tree[x][1-z]=y;
    father[y]=x;
    update(y);
    update(x);
    if (pp[y]){
        pp[x]=pp[y];
        pp[y]=0;
    }
}
void clear(int x){
    if (bz[x]){
        bz[tree[x][0]]^=1;
        bz[tree[x][1]]^=1;
        swap(tree[x][0],tree[x][1]);
        bz[x]=0;
    }
}
void remove(int x,int y){
    cnt=0;
    while (x!=y){
        sta[++cnt]=x;
        x=father[x];
    }
    while (cnt){
        clear(sta[cnt]);
        cnt--;
    }
}
void splay(int x,int y){
    remove(x,y);
    while (father[x]!=y){
        if (father[father[x]]!=y)
            if (pd(x)==pd(father[x])) rotate(father[x]);else rotate(x);
        rotate(x);
    }
}
void access(int x){
    int y;
    splay(x,0);
    if (tree[x][1]){
        pp[tree[x][1]]=x;
        father[tree[x][1]]=0;
        tree[x][1]=0;
        update(x);
    }
    while (x){
        splay(x,0);
        y=pp[x];
        if (!y) break;
        splay(y,0);
        if (tree[y][1]){
            pp[tree[y][1]]=y;
            father[tree[y][1]]=0;
        }
        tree[y][1]=x;
        pp[x]=0;
        father[x]=y;
        update(y);
        x=y;
    }
}
void makeroot(int x){
    access(x);
    splay(x,0);
    bz[x]^=1;
}
int newnode(int x){
    sum[++top]=sum[x];
    left[top]=left[x];
    right[top]=right[x];
    return top;
}
void change(int &p,int l,int r,int a,int b){
    p=newnode(p);
    sum[p]+=b;
    if (l==r) return;
    int mid=(l+r)/2;
    if (a<=mid) change(left[p],l,mid,a,b);else change(right[p],mid+1,r,a,b);
}
int query(int p,int l,int r,int a,int b){
    if (a>b) return 0;
    if (l==a&&r==b) return sum[p];
    int mid=(l+r)/2;
    if (b<=mid) return query(left[p],l,mid,a,b);
    else if (a>mid) return query(right[p],mid+1,r,a,b);
    else return query(left[p],l,mid,a,mid)+query(right[p],mid+1,r,mid+1,b);
}
void write(int x){
    if (!x){
        putchar('0');
        putchar('\n');
        return;
    }
    cnt=0;
    while (x){
        sta[++cnt]=x%10;
        x/=10;
    }
    while (cnt){
        putchar(sta[cnt]+'0');
        cnt--;
    }
    putchar('\n');
}
int main(){
    n=read();m=read();q=read();
    tot=now=n;
    fo(i,1,n) key[i]=m+1,num[i]=i;
    fo(i,1,m){
        j=read();k=read();
        edge[i][0]=j;edge[i][1]=k;
        root[i]=root[i-1];
        tot++;
        key[tot]=i;
        num[tot]=tot;
        if (j==k){
            ans[i]=ans[i-1];
            continue;
        }
        if (getfa(j)!=getfa(k)){
            fa[getfa(k)]=getfa(j);
            now--;
            makeroot(k);
            splay(k,0);
            pp[k]=tot;
            pp[tot]=j;
            change(root[i],1,m,i,1);
        }
        else{
            makeroot(j);
            access(k);
            splay(k,0);
            l=num[k];
            change(root[i],1,m,l-n,-1);
            makeroot(l);
            access(l);
            splay(edge[l-n][0],0);
            pp[edge[l-n][0]]=0;
            splay(edge[l-n][1],0);
            pp[edge[l-n][1]]=0;
            makeroot(k);
            splay(k,0);
            pp[k]=tot;
            pp[tot]=j;
            change(root[i],1,m,i,1);
        }
        ans[i]=now;
    }
    while (q--){
        l=read();r=read();
        now=ans[r];
        now+=query(root[r],1,m,1,l-1);
        write(now);
    }
}
<think>好的,用户想下载TTF格式的中文字体文件,并了解文件来源及安装方法。首先,我需要回忆之前提供的引用内容,看看是否有相关信息。引用[1]提到matplotlib支持TTF和AFM字体,但用户的问题是关于如何下载和安装TTF中文字体,所以可能需要更多的外部资源信息。引用[2]详细解释了TTF和OTF的区别,说明TTF的兼容性较好,适合用户需求。引用[3]提到了替换系统字体文件的步骤,但用户需要的是下载和安装方法,可能需要扩展安装步骤。 首先,用户需要知道从哪里下载合法的TTF中文字体。常见的来源包括官方网站、授权平台和开源字体库。比如,Google Fonts现在支持部分中文字体,但可能选择有限。Adobe Fonts可能有更多选项,但需要订阅。另外,像方正、汉仪等字体公司提供正版字体,但需要购买。开源项目如思源黑体、站酷系列字体是免费可商用的,适合用户。 接下来是下载步骤。需要指导用户访问这些网站,搜索所需字体,并选择TTF格式下载。要提醒用户注意版权问题,避免侵权。 然后是安装方法。对于Windows,用户可以通过右键安装,或者将字体文件复制到Fonts目录。Mac用户可以使用字体册,或者替换系统字体文件,但引用[3]警告不要直接替换整个文件夹,以免乱码。需要详细说明正确步骤,确保用户操作无误。 可能的问题:用户可能不知道哪些网站可信,需要推荐可靠的来源。同时,安装步骤可能因操作系统不同而有差异,需分开说明。还要强调版权的重要性,避免用户使用非法字体。 最后,生成相关问题,帮助用户深入了解字体格式的选择和高级安装方法,比如命令行或开发环境中的使用。</think>### 如何下载和安装TTF格式中文字体 #### 一、TTF中文字体文件来源 1. **官方字体厂商平台** - 方正字库([www.foundertype.com](https://www.foundertype.com))、汉仪字库([www.hanyi.com.cn](https://www.hanyi.com.cn))等提供正版中文字体,需付费购买后下载[^2]。 - 部分字体提供TTF格式,需在下载页面确认文件类型。 2. **开源免费字体库** - **思源系列**(如思源黑体、思源宋体):由Adobe与Google合作开发,支持中文,可免费商用。下载地址:[GitHub Adobe Fonts](https://github.com/adobe-fonts) - **站酷系列**(如站酷酷黑、站酷小薇LOGO体):提供免费可商用的中文字体,访问[站酷网](https://www.zcool.com.cn/special/ztxz/)下载。 3. **字体聚合平台** - **Google Fonts**([fonts.google.com](https://fonts.google.com)):搜索支持中文的字体(如Noto Sans CJK),选择TTF格式下载。 - **FontSpace**([www.fontspace.com](https://www.fontspace.com)):筛选"Chinese"分类,注意检查授权信息。 #### 二、安装方法 1. **Windows系统** - **右键安装**:双击下载的`.ttf`文件,点击窗口中的“安装”按钮。 - **手动复制**:将文件复制到系统字体目录:`C:\Windows\Fonts`。 2. **macOS系统** - **字体册安装**:双击`.ttf`文件,点击“安装字体”按钮。 - **终端命令安装**(高级): ```bash cp /path/to/font.ttf /Library/Fonts/ # 全局安装 cp /path/to/font.ttf ~/Library/Fonts/ # 当前用户安装 ``` 3. **注意事项** - 若替换系统字体(如修复乱码),需进入`/System/Library/Fonts/`目录后**逐个替换文件**,不可直接覆盖文件夹[^3]。 - 开发场景(如matplotlib)需刷新字体缓存:删除`~/.matplotlib/fontlist-*.json`后重启程序[^1]。 #### 三、版权与授权 - 商用字体需确认授权范围,开源字体(如思源系列)遵循OFL协议。 - 部分免费字体仅限个人使用,需仔细阅读许可文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值