noip2017酱油记前篇

noip day0

马上就要打酱油了>_<,真是害怕。昨天就整理了一下noip要写的模板

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=100000+233;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
struct saber{
int an,l,r;
}t[maxn<<2];
int tt[maxn],a[maxn],b[maxn],dp[maxn],ans,n;
inline void build(int k,int l,int r){
    t[k].l=l;t[k].r=r;
    if(l==r)return ;
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
}
inline int ask(int k,int x,int y){
    int l=t[k].l,r=t[k].r;
    if(l==x&&r==y)return t[k].an;
    int mid=l+r>>1;
    if(mid>=y)return ask(k<<1,x,y);
    else if(x>mid)return ask(k<<1|1,x,y);
    else return max(ask(k<<1,x,mid),ask(k<<1|1,mid+1,y));
}
inline void add(int k,int wi,int fin){
    int l=t[k].l,r=t[k].r;
    if(l==fin&&r==fin){t[k].an=wi;return;}
    int mid=l+r>>1;
    if(mid>=fin)add(k<<1,wi,fin);
    else add(k<<1|1,wi,fin);
    t[k].an=max(t[k<<1].an,t[k<<1|1].an);
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<=n;i++)b[i]=read();
    for(int i=1;i<=n;i++)tt[b[i]]=i;
    for(int i=1;i<=n;i++)a[i]=tt[a[i]];
    build(1,1,n);
    for(int i=1;i<=n;i++){
        int x=ask(1,1,a[i]);
        dp[i]=x+1;
        add(1,dp[i],a[i]);
        ans=max(ans,dp[i]);
    }
    cout<<ans;
}

【模板】最长公共子序列

类似导弹拦截



#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<vector>
#define _x .first
#define _y .second
using namespace std;
const int maxn=10000+2333;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<3)+(an<<1)+(ch^48);ch=getchar();}
    return an;
}
int tmp;
struct saber{
int l,r,t,id;
}q[maxn];
vector< pair<int,int > > change;

int n,m,a[maxn],block,link[maxn],cntq,cnt,ans[maxn];
int color[maxn*10],size;
char c;
bool operator <(saber x,saber y){return (link[x.l]<link[y.l])||(link[x.l]==link[y.l]&&x.r<y.r)||(link[x.l]==link[y.l]&&x.r==y.r&&x.t<y.t);}

inline void Change(int x,int i){
    if(change[x] _x>=q[i].l&&change[x] _x<=q[i].r){
        color[a[change[x] _x]]--;
        if(color[a[change[x] _x]]==0)tmp--;
        if(color[change[x] _y]==0)tmp++;
        color[change[x] _y]++;
    }
    swap(a[change[x] _x],change[x] _y);
}
int main(){
//    ios::sync_with_stdio(0);
    cin>>n>>m;
    size=sqrt(n);
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=m;i++){
        link[i]=block+1;
        if(!(i%size))block++;
    }
    change.push_back(make_pair(0,0));
    for(int i=1;i<=m;i++){
        cin>>c;
        if(c==‘R‘){
            ++cntq;
            int x,y;cin>>x>>y;
            change.push_back( make_pair(x,y) );
        }
        else{
            int x,y;cin>>x>>y;
            q[++cnt]=(saber){x,y,cntq,cnt};
        }
    }
    sort(q+1,q+1+cnt);
    int L=0,R=0,now=0;
    for(int i=1;i<=cnt;i++){
        while(L<q[i].l){color[a[L]]--;if(!color[a[L]])tmp--;L++;}
        while(L>q[i].l){L--;color[a[L]]++;if(color[a[L]]==1)tmp++;}
        while(R<q[i].r){R++;color[a[R]]++;if(color[a[R]]==1)tmp++;}
        while(R>q[i].r){color[a[R]]--;if(color[a[R]]==0)tmp--;R--;}
        while(now<q[i].t){now++,Change(now,i);}
        while(now>q[i].t){Change(now,i);now--;}
        ans[q[i].id]=tmp;
    }
    for(int i=1;i<=cnt;i++)cout<<ans[i]<<"\n";
    return 0;
}

【模板】分块/带修改莫队(数颜色)

分块处理<优雅的暴力>



#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define ll long long
const int mod=1e9+7;
using namespace std;
int n,T;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
struct saber{
ll a[5][5];
}b,a;
saber operator *(saber A,saber B){
    saber re;
    memset(re.a,0,sizeof re.a);
    for(int k=1;k<=3;k++)
    for(int i=1;i<=3;i++)
    for(int j=1;j<=3;j++)
    re.a[i][j]=(re.a[i][j]+A.a[i][k]*B.a[k][j])%mod;
    return re;
}
inline saber work(saber x,int y){
    saber re;
    re=x;
    while(y){
        if(y&1)re=re*x;
        x=x*x;
        y>>=1;
    }
    return re;
}
int main(){
    b.a[1][3]=1;b.a[2][1]=1;
    b.a[3][3]=1;b.a[3][2]=1;
    a.a[1][1]=1;a.a[1][2]=1;a.a[1][3]=1;
    T=read();
    while(T){
        T--;
        n=read();
        if(n<=3){cout<<"1\n";continue;}
        saber k=work(b,n-4);
        k=a*k;
        cout<<k.a[1][3]<<"\n";
    }
}

P1939 【模板】矩阵加速(数列)

推出矩阵乱搞就好了



#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<algorithm>
using namespace std;
int read(){
    int an=0,f=1;
    char ch=getchar();
    while(!(‘0‘<=ch&&ch<=‘9‘)){if(ch==‘-‘)f=-f;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
const int maxn=5099;
const int maxm=200999;
int fa[maxn],cnt,so[maxm];
long long ans;
int m,n,tot;
struct saber{
int from,to,wi;
}b[maxm];
void add(int x,int y,int z){
    cnt++;
    b[cnt].from=x;
    b[cnt].to=y;
    b[cnt].wi=z;
}
bool pai(int x,int y){
    return b[x].wi<b[y].wi;
}
int found(int x){
    if(fa[x]!=x)fa[x]=found(fa[x]);
    return fa[x];
}
int main(){
    n=read();m=read();
    for(int i=1;i<=m;i++){
        int x,y,z;
        x=read();y=read();z=read();
        add(x,y,z);
    }
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++)so[i]=i;
    sort(so+1,so+m+1,pai);
    for(int i=1;i<=m;i++){
        int x=b[so[i]].from;
        int y=b[so[i]].to;
        int f1=found(x);int f2=found(y);
        if(f1!=f2){ans+=b[so[i]].wi;fa[f1]=f2;}
    }
    cout<<ans;
    return 0;
}

【模板】最小生成树

记得路径压缩



#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define IN 599962
int a[IN],c[IN];
int m,n;
int LO(int i){return (-i)&i;}
int  ans(int k){
     int ans=0;
     for(int i=k;i>0;i-=LO(i))ans+=c[i];
     return ans;
}
void F(int k){
    printf("%d",ans(k));
}
void F(int k1,int k2,int k3){
     for(int i=k1;i<=n;i+=LO(i))c[i]+=k3;
     for(int i=k2+1;i<=n;i+=LO(i))c[i]-=k3;
     }
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
      scanf("%d",&a[i]);
      for(int j=i;j<=n;j+=LO(j))c[j]+=a[i];
      int j;j=i+1;
       for(j;j<=n;j+=LO(j))c[j]-=a[i];
      }
    for(int j=1;j<=m;j++){
      int s;
      scanf("%d",&s);
     if(s==1){int k1,k2,k3;
        scanf("%d%d%d",&k1,&k2,&k3);
        F(k1,k2,k3);
     }
     else{int k;
          scanf("%d",&k);
          F(k);
          printf("\n");
     }
    }
    return 0;
}

P3368 【模板】树状数组 2

查分树状数组



#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=10000+2333;
const ll mod=23333333333ll;
const int sand=107;
char ch[maxn];
ll a[maxn];
ll hax(){
    int len=strlen(ch);
    ll re=0;
    for(int i=0;i<len;i++)re=(re*sand+ch[i])%mod;
    return re;
}
int n;
int main(){
    ios::sync_with_stdio(0);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>ch;
        a[i]=hax();
    }
    sort(a+1,a+1+n);
    int tot=unique(a+1,a+1+n)-a-1;
    cout<<tot;
    return 0;
}

【模板】字符串哈希

哈希判断是否重复,wa了该取模数。O2之后某个溢出哈希就会挂~\(≧▽≦)/~啦啦啦


最短路

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<cstring>
#define _X .first
#define _Y .second
#define ll long long
using namespace std;
const int maxn=10000+2333;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
int n,m,S,cnt;
int f[maxn];
ll dis[maxn];
pair<ll,int>now;
priority_queue<pair<ll,int> >q;
struct saber{
int nex,to,wi;
}b[(500000<<1)+233];
inline void add(int x,int y,int z){
    cnt++;
    b[cnt].wi=z;
    b[cnt].to=y;
    b[cnt].nex=f[x];
    f[x]=cnt;
}
void dij(){
    for(int i=1;i<=n;i++)dis[i]=2147483647;
    dis[S]=0;
    q.push(make_pair(0,-S));
    while(!q.empty()){
        now=q.top();q.pop();
        int x=-now _Y;
        for(int i=f[x];i;i=b[i].nex){
            int v=b[i].to;
            if(dis[v]>dis[x]+b[i].wi){
                dis[v]=dis[x]+b[i].wi;
                q.push(make_pair(-dis[v],-v));
            }
        }
    }
}
int main(){
    n=read();m=read();S=read();
    for(int i=1;i<=m;i++){
        int x=read(),y=read(),z=read();
        add(x,y,z);
    }
    dij();
    for(int i=1;i<=n;i++)
    cout<<dis[i]<<" ";
    return 0;
}

dijkstra

传说他稳定

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<algorithm>
#define ll long long
using namespace std;
const ll INT=2147483647LL;
ll read(){
    ll an=0,f=1;
    char ch=getchar();
    while(!(‘0‘<=ch&&ch<=‘9‘)){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
ll x,y,z;
ll f[10000+99],spf[10000+99],m,n,k,wi[500099],sum;
bool cx[10000+99];
queue<ll>q;
struct saber{
int nex,to;
}b[500099];
void add(ll x,ll y,ll z){
    sum++;
    b[sum].nex=f[x];
    b[sum].to=y;
    f[x]=sum;
    wi[sum]=z;
}
void spfa(){
    while(!q.empty()){
        ll v=q.front();
        q.pop();cx[v]=0;
        for(int i=f[v];i;i=b[i].nex){
            if(spf[b[i].to]>spf[v]+wi[i]){
            spf[b[i].to]=spf[v]+wi[i];
            if(!cx[b[i].to]){
                q.push(b[i].to);
                cx[b[i].to]=1;}
            }
        }
    }
}
int main(){
    n=read();m=read();k=read();
    for(int i=0;i<=n;i++)spf[i]=INT;
    for(int i=1;i<=m;i++){
        x=read();y=read(),z=read();
        add(x,y,z);}
    q.push(k);spf[k]=0;
    cx[k]=1;
    spfa();
    for(int i=1;i<=n;i++)cout<<spf[i]<<" ";
    return 0;
}

SPFA

不知道双向队列那个快?[>_<]



线段树模板

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
using namespace std;
const ll maxn=100000+233;
inline ll read(){
    ll an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||‘9‘<ch){ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<1)+(an<<3)+(ch^48);ch=getchar();}
    return an;
}
struct saber{
ll l,r,lazy,sum;
}t[maxn<<4];
ll n,m;
inline void build(ll k,ll l,ll r){
    t[k].l=l;t[k].r=r;
    if(l==r){t[k].sum=read();return;}
    ll mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
}
inline void change(ll k){
    ll x=t[k].r+1-t[k].l;
    t[k<<1].lazy+=t[k].lazy;
    t[k<<1|1].lazy+=t[k].lazy;
    t[k<<1].sum+=t[k].lazy*(x+1>>1);
    t[k<<1|1].sum+=t[k].lazy*(x>>1);
    t[k].lazy=0;
}
inline ll ask(ll k,ll x,ll y){
    ll l=t[k].l,r=t[k].r;
    if(t[k].lazy)change(k);
    if(y==r&&l==x){return t[k].sum;}
    ll mid=l+r>>1;
    if(y<=mid)return ask(k<<1,x,y);
    else if(mid<x)return ask(k<<1|1,x,y);
    else return ask(k<<1,x,mid)+ask(k<<1|1,mid+1,y);
}
inline void add(ll k,ll x,ll y,ll wi){
    if(t[k].lazy)change(k);
    ll l=t[k].l,r=t[k].r;
    if(y==r&&l==x){t[k].sum+=(r-l+1)*wi;t[k].lazy+=wi;return;}
    ll mid=l+r>>1;
    if(y<=mid)add(k<<1,x,y,wi);
    else if(mid<x)add(k<<1|1,x,y,wi);
    else {add(k<<1,x,mid,wi);add(k<<1|1,mid+1,y,wi);}
    t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
}
int main(){
    n=read();m=read();
    build(1,1,n);
    for(;m;m--){
        ll pd=read(),x=read(),y=read();
        if(pd==1){
            ll v=read();
            add(1,x,y,v);
        }
        else {
            cout<<ask(1,x,y)<<"\n";
        }
    }
}

线段树

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
inline ll read(){
    ll an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<3)+(an<<1)+(ch^48);ch=getchar();}
    return an;
}
const ll maxn=100000+233;
ll link[maxn],a[maxn],b[3000],size,add[3000],block,n,m,l[3000],r[3000];
int main(){
    ios::sync_with_stdio(0);
    n=read();m=read();
    size=sqrt(n);
    l[1]=1;
    for(ll i=1;i<=n;i++)a[i]=read();
    for(ll i=1;i<=n;i++){
        link[i]=block+1;
        b[block+1]+=a[i];
        if(!(i%size)){
            block++;
            l[block+1]=i+1;
            r[block]=i;
        }
    }
    if(n%size)r[++block]=n;
    for(;m;m--){
        ll pd=read();
        if(pd==1){
            ll L=read(),R=read(),p=read();
            ll chl=link[L],chr=link[R];
            if(chl^chr){
                for(ll i=L;i<=r[chl];i++)a[i]+=p,b[chl]+=p;
                for(ll i=l[chr];i<=R;i++)a[i]+=p,b[chr]+=p;
                for(ll i=chl+1;i<chr;i++)add[i]+=p;
            }
            else{
                for(ll i=L;i<=R;i++)a[i]+=p;
            }
        }
        else {
            ll ans=0,L=read(),R=read();
            ll chl=link[L],chr=link[R];
            if(chl^chr){
                for(ll i=L;i<=r[chl];i++)ans+=add[chl]+a[i];
                for(ll i=l[chr];i<=R;i++)ans+=add[chr]+a[i];
                for(ll i=chl+1;i<chr;i++)ans+=add[i]*(r[i]-l[i]+1)+b[i];
            }
            else{
                for(ll i=L;i<=R;i++)ans+=a[i]+add[i];
            }
            cout<<ans<<"\n";
        }
    }
}

分块

分块还是好写



【模板】树状数组 1

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define IN 5999620
int a[IN],c[IN];
int LO(int x){return (-x)&x;}
int m,n;
int q,w,e;
void FF(int x,int y){
       for(int k=x;k<=n;k+=LO(k))
       c[k]+=y;
}
int S(int s){int ans=0;
    for(int j=s;j>0;j-=LO(j))
    ans+=c[j];
    return ans;
}
void FFF(int i,int j){
        cout<<S(j)-S(i)<<endl;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){scanf("%d",&a[i]);
     for(int j=i;j<=n;j+=LO(j))
      c[j]+=a[i];}
     for(int i=1;i<=m;i++){
     scanf("%d%d%d",&q,&w,&e);
      if(q==1)FF(w,e);
      else FFF(w-1,e);
     }
     return 0;
}

树状数组

就是2去掉差分



【模板】堆

手打堆

#include<iostream>
#include<cstdio>
#include<cstdlib>
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<3)+(an<<1)+ch-48;ch=getchar();}
    return an*f;
}
const int maxn=100000+23;
using namespace std;
int q;
int t[maxn],tot;
inline void add(int x){
    tot++;
    t[tot]=x;
    for(int i=tot,j=i>>1;j;i=j,j=i>>1){
        if(t[j]>t[i])swap(t[i],t[j]);
    }
}
inline void pop(){
    t[1]=t[tot];tot--;
    for(int i=1,j=i<<1;j<=tot;i=j,j=i<<1){
        if(j+1<=tot&&t[j+1]<t[j])
        ++j;
        if(t[i]<t[j])break;
        else swap(t[i],t[j]);
    }
}
inline int getans(){
    return t[1];
}
int main(){
    q=read();
    ios::sync_with_stdio(0);
    while(q){
        q--;
        int x=read();
        if(x==1)add( read() );
        else if(x==2)cout<<getans()<<"\n";
        else pop();
    }
}



【模板】最近公共祖先(LCA)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int read(){
    int an=0,f=1;
    char ch=getchar();
    while(!(‘0‘<=ch&&ch<=‘9‘)){if(ch==‘-‘)f=-f;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return f*an;
}
const int maxn=500000+999;
int n,m,s,cnt;
int f[maxn],fa[maxn][25],deep[maxn];
bool vis[maxn];
int x,y;
struct saber{
int nex,to;
}b[maxn*2];
void add(int x,int y){
    cnt++;
    b[cnt].nex=f[x];
    b[cnt].to=y;
    f[x]=cnt;}
void dfs(int x){
    vis[x]=1;
    for(int i=f[x];i;i=b[i].nex){
        int v=b[i].to;
        if(!vis[v]){
            fa[v][0]=x;deep[v]=deep[x]+1;
        for(int j=1;j<=20;j++){
            if(!fa[fa[v][j-1]][j-1])break;
            fa[v][j]=fa[fa[v][j-1]][j-1];}
            dfs(v);
        }
    }
}
int lca(int u,int v){
    if(deep[u]>deep[v])swap(u,v);
    for(int i=20;i>=0;i--)
        if(deep[fa[v][i]]>=deep[u])v=fa[v][i];
    if(u==v)return u;
    for(int i=20;i>=0;i--)
        if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
    if(u==v)return u;
    return fa[u][0];
}
void Lca(int x,int y){
    int ans=lca(x,y);
    printf("%d\n",ans);
}
int main(){
    n=read();m=read();s=read();
    for(int i=1;i<n;i++){
        x=read();y=read();
        add(x,y);add(y,x);}
    deep[s]=1;
    dfs(s);
    for(int i=1;i<=m;i++){
        x=read();y=read();
        Lca(x,y);}
    return 0;
}

倍增

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<algorithm>
using namespace std;
int read(){
    int an=0,f=1;char ch=getchar();
    while(!(‘0‘<=ch&&ch<=‘9‘)){if(ch==‘-‘)f=-f;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
int n,m,s,cnt,qf[500099],f[500099],fa[500099],ans[500099<<1];
int x,y;
bool vis[500099];
int found(int x){
    if(fa[x]!=x)fa[x]=found(fa[x]);
    return fa[x];}
struct saber{
int to,nex;
}b[500099<<1];
struct question{
int to,nex;
}qu[500099<<1];
void add(int x,int y){
    cnt++;b[cnt].to=y;
    b[cnt].nex=f[x];f[x]=cnt;
}
void add(int x,int y,int z){
    qu[z].to=y;
    qu[z].nex=qf[x];
    qf[x]=z;
}
void dfs(int x){
    fa[x]=x;vis[x]=1;
    for(int i=f[x];i;i=b[i].nex){
        int v=b[i].to;
        if(!vis[v]){
            dfs(v);
            fa[v]=x;
        }
    }
    for(int i=qf[x];i;i=qu[i].nex){
        int v=qu[i].to;
        if(vis[v]){
            ans[i]=found(v);
            if(i&1)ans[i+1]=ans[i];
            else ans[i-1]=ans[i];
        }
    }
}
int main(){
    n=read();m=read();s=read();
    for(int i=1;i<n;i++){
        int x,y;x=read();y=read();
        add(x,y);add(y,x);
    }
    for(int i=1;i<=m;i++){
        x=read();y=read();
        add(x,y,(i<<1)-1);add(y,x,(i<<1));
    }
    dfs(s);
    for(int i=1;i<=m;i++){
        printf("%d\n",ans[i<<1]);}
    return 0;
}

tarjian



【模板】网络最大流

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
const int maxn=100000+2333;
const int maxm=100000+99999;
const int INT=1e7;
using namespace std;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||‘9‘<ch){ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<1)+(an<<3)+(ch^48);ch=getchar();}
    return an;
}
int f[maxn],S,T,n,m,cnt=1;
struct saber{
int wi,nex,to;
}b[maxn<<2];
inline void add(int x,int y,int z){
    cnt++;
    b[cnt].to=y;
    b[cnt].wi=z;
    b[cnt].nex=f[x];
    f[x]=cnt;
}
queue<int>q;
int dis[maxn];
bool vis[maxn];
inline int bfs(){
    while(!q.empty())q.pop();
    q.push(S);
    memset(dis,-1,sizeof dis);
    dis[S]=0;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=f[x];i;i=b[i].nex){
            int v=b[i].to;
            if(dis[v]<0&&b[i].wi){
                dis[v]=dis[x]+1;
                if(v==T)return 1;
                q.push(v);
            }
        }
    }
    return 0;
}
inline int dfs(int x,int li){
    if(x==T||!li)return li;
    int used=li;
    vis[x]=1;
    for(int i=f[x];i;i=b[i].nex){
        int v=b[i].to;
        if(!vis[v]){
            if(dis[v]==dis[x]+1&&used&&b[i].wi){
                int re=dfs(v,min(b[i].wi,used));
                used-=re;
                b[i].wi-=re;
                b[i^1].wi+=re;
            }
        }
    }
    return li-used;
}
void dinic(){
    int ans=0;
    while(bfs()){
        memset(vis,0,sizeof vis);
        ans+=dfs(S,INT);
    }
    cout<<ans;
}
int main(){
    n=read();m=read();S=read();T=read();
    for(int i=1;i<=m;i++){
        int x=read(),y=read(),z=read();
        add(x,y,z);
        add(y,x,0);
    }
    dinic();
    return 0;
}

网络流

真noip



【模板】最小费用最大流

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
const int maxn=100000+2333;
const int maxm=100000+99999;
const int INT=1e7;
using namespace std;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||‘9‘<ch){ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<1)+(an<<3)+(ch^48);ch=getchar();}
    return an;
}
int f[maxn],S,T,n,m,cnt=1;
struct saber{
int wi,nex,to,fi;
}b[maxn<<2];
inline void add(int x,int y,int z,int fi){
    cnt++;
    b[cnt].to=y;
    b[cnt].wi=z;
    b[cnt].fi=fi;
    b[cnt].nex=f[x];
    f[x]=cnt;
}
deque<int>q;
int dis[maxn];
bool vis[maxn],in[maxn];
inline int bfs(){
    while(!q.empty())q.pop_front();
    q.push_back(S);
    for(int i=0;i<=n+2;i++)dis[i]=INT;
    memset(in,0,sizeof in);
    dis[S]=0;
    while(!q.empty()){
        int x=q.front();q.pop_front();in[x]=0;
        for(int i=f[x];i;i=b[i].nex){
            int v=b[i].to;
            if(dis[v]>dis[x]+b[i].fi&&b[i].wi){
                dis[v]=dis[x]+b[i].fi;
                if(!in[v]){
                in[v]=1;
                if(!q.empty()&&dis[v]<dis[q.front()])q.push_front(v);
                else q.push_back(v);
                }
            }
        }
    }
    return dis[T]<INT;
}
inline int dfs(int x,int li){
    if(x==T||!li)return li;
    int used=li;
    vis[x]=1;
    for(int i=f[x];i;i=b[i].nex){
        int v=b[i].to;
        if(!vis[v]){
            if(dis[v]==dis[x]+b[i].fi&&used&&b[i].wi){
                int re=dfs(v,min(b[i].wi,used));
                used-=re;
                b[i].wi-=re;
                b[i^1].wi+=re;
            }
        }
    }
    return li-used;
}
void dinic(){
    int ans=0;
    int fe=0;
    while(bfs()){
        memset(vis,0,sizeof vis);
        int v=dfs(S,INT);
        ans+=v;
        fe+=dis[T]*v;
    }
    cout<<ans<<" "<<fe;
}
int main(){
    n=read();m=read();S=read();T=read();
    for(int i=1;i<=m;i++){
        int x=read(),y=read(),z=read(),fi=read();
        add(x,y,z,fi);
        add(y,x,0,-fi);
    }
    dinic();
    return 0;
}

费用流

在网络流上加最短路



【模板】负环

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=200000+2333;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
struct saber{
int nex,wi,to;
}b[maxn<<1];
int f[maxn],dis[maxn],T,cnt,n,m,flag;
bool vis[maxn];
inline void add2(int x,int y,int z){
    cnt++;
    b[cnt].to=y;
    b[cnt].wi=z;
    b[cnt].nex=f[x];
    f[x]=cnt;
}
inline void add(int x,int y,int z){
    if(z>0)add2(x,y,z),add2(y,x,z);
    else add2(x,y,z);
}
inline void dfs(int x){
    if(vis[x]){flag=1;return ;}
    vis[x]=1;
    for(int i=f[x];i&&!flag;i=b[i].nex){
        int v=b[i].to;
        if(dis[v]>dis[x]+b[i].wi){
            dis[v]=dis[x]+b[i].wi;
            dfs(v);
        }
    }
    vis[x]=0;
}
int main(){
    T=read();
    ios::sync_with_stdio(0);
    while(T){T--;
        flag=0;
        cnt=0;
        memset(vis,0,sizeof vis);
        memset(dis,0,sizeof dis);
        memset(f,0,sizeof f);
        n=read();m=read();
        for(int i=1;i<=m;i++){
            int x=read(),y=read(),z=read();
            add(x,y,z);
        }
        for(int i=1;i<=n&&!flag;i++){
            dfs(i);
        }
        if(!flag)cout<<"N0\n";
        else cout<<"YE5\n";
    }
}

负环

dfs判负环



【模板】二分图匹配

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int maxn=3000;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<3)+(an<<1)+ch-‘0‘;ch=getchar();}
    return an*f;
}
int f[maxn<<1],ans,cnt,n,m,e;
struct saber{
int nex,to;
}b[5000000];
inline void add(int x,int y){
    cnt++;
    b[cnt].to=y;
    b[cnt].nex=f[x];
    f[x]=cnt;
}
int in[maxn<<1];
bool vis[maxn<<1];
inline int dfs(int x){
    for(int i=f[x];i;i=b[i].nex){
        int v=b[i].to;
        if(!in[v]){in[v]=x;return 1;}
    }
    for(int i=f[x];i;i=b[i].nex){
        int v=b[i].to;
        if(vis[v])continue;
        vis[v]=1;
        if(dfs(in[v])){in[v]=x;return 1;}
    }
    return 0;
}
int main(){
    n=read();m=read();e=read();
    for(int i=1;i<=e;i++){
    int x=read(),y=read();
        if(y>m);
        else add(x,n+10+y);
    }
    for(int i=1;i<=n;i++){
    memset(vis,0,sizeof vis);
    if(dfs(i))ans++;
    }
    cout<<ans;
}

匈牙利算法

莫名其妙<网络流跑不A(竟然不是T



【模板】缩点

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
#define ll long long
using namespace std;
const int maxn=1e4+233+17+9;
const int maxm=1e5+2333+17+9+4950;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<3)+(an<<1)+ch-‘0‘;ch=getchar();}
    return an*f;
}
int scc,f[maxn],ff[maxn],id;
int dag[maxn],dfn[maxn],low[maxn],wi[maxn];
int bel[maxn];
int dp[maxn],cnt,ans,n,m,ins[maxn];
bool vis[maxn],in[maxn];
struct saber{
int nex,to;
}b[maxm],bb[maxm];
stack<int>s;
inline void add(int x,int y){
    cnt++;
    b[cnt].to=y;
    b[cnt].nex=f[x];
    f[x]=cnt;
}
inline void add2(int x,int y){
    cnt++;
    ins[y]++;
    bb[cnt].to=y;
    bb[cnt].nex=ff[x];
    ff[x]=cnt;
}
inline void dfs(int x){
    id++;
    dfn[x]=low[x]=id;
    in[x]=vis[x]=1;
    s.push(x);
    for(int i=f[x];i;i=b[i].nex){
        int v=b[i].to;
        if(!vis[v]){
            dfs(v);
            low[x]=min(low[x],low[v]);
        }
        else if(in[v])low[x]=min(low[x],dfn[v]);
    }
    if(dfn[x]==low[x]){
        int z=22333;scc++;
        while(z!=x){
            z=s.top();
            bel[z]=scc;
            dag[scc]+=wi[z];
            in[z]=0;
            s.pop();
        }
    }
}
queue<int>q;
inline void rebuild(){
    cnt=1;
    for(int i=1;i<=n;i++){
        for(int j=f[i];j;j=b[j].nex){
            int v=b[j].to;
            if(bel[i]!=bel[v])add2(bel[i],bel[v]);
        }
    }
}
inline void top_sort(){
    int flag,l=1;
    while(l<=n){
    memset(vis,0,sizeof vis);
    memset(dp,0,sizeof dp);
    while(l<=n){
    if(!ins[l]){q.push(l);flag=l;break;}
    else l++;
    }
    dp[flag]=dag[flag];
    while(!q.empty()){
        int x=q.front();q.pop();vis[x]=0;
        for(int i=ff[x];i;i=bb[i].nex){
            int v=bb[i].to;
            if(dp[v]<dp[x]+dag[v]){
            dp[v]=dp[x]+dag[v];
            if(!vis[v]){
                q.push(v);
                vis[v]=1;
                    }
                    }
            }
        ans=max(ans,dp[x]);
        }
        l=l+1;
        }
}
int main(){
    n=read();m=read();
    for(int i=1;i<=n;i++)wi[i]=read();
    for(int i=1;i<=m;i++){
        int x=read(),y=read();
        add(x,y);
    }
    for(int i=1;i<=n;i++)
    if(!vis[i])dfs(i);
    rebuild();
    top_sort();
    cout<<ans;
    return 0;
}

dp

不要跑最短路>>



【模板】割点(割顶)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
#define ll long long
using namespace std;
const int maxn=100000+2333+17+9+4950;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=(an<<3)+(an<<1)+ch-‘0‘;ch=getchar();}
    return an*f;
}
int f[maxn],n,m,cnt=1,id;
bool cut[maxn],vis[maxn];
int dfn[maxn],low[maxn],ans;
struct saber{
int nex,to;
}b[maxn<<1];
inline void add(int x,int y){
    cnt++;
    b[cnt].to=y;
    b[cnt].nex=f[x];
    f[x]=cnt;
}
inline int dfs(int x,int fa){
    int sum=0;bool cu=0;
    id++;
    dfn[x]=low[x]=id;vis[x]=1;
    for(int i=f[x];i;i=b[i].nex){
        int v=b[i].to;
        if(v==fa)continue;
        if(!vis[v]){
            sum++;
            dfs(v,x);
            low[x]=min(low[x],low[v]);
            if(low[v]>=dfn[x])cu=1;
        }
        else low[x]=min(low[x],dfn[v]);
    }
    if(!fa){if(sum>1)ans++,cut[x]=1;}
    else if(cu)ans++,cut[x]=1;
}
int main(){
    n=read();m=read();
    for(int i=1;i<=m;i++){
        int x=read(),y=read();
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;i++)
    if(!vis[i])dfs(i,0);
    cout<<ans<<"\n";
    for(int i=1;i<=n;i++)if(cut[i])cout<<i<<" ";
    return 0;
}

割点

贪心,先找根,然后判下面是否割



【模板】卢卡斯定理

#include<iostream>
#include<cstdlib>
#define ll long long
using namespace std;
ll T,p;
ll f[500000];
ll ks(ll y,ll k){
    ll s=y,ans=1;
    while(k){
        if(k&1)ans=ans*s%p;
        s=s*s%p;
        k>>=1;
    }
    return ans%p;
}
ll C(ll n,ll m){
    if(m>n)return 0;
    return f[n]*ks(f[m]*f[n-m],p-2)%p;
}
ll Luc(ll n,ll m){
    if(!m)return 1;
    return (Luc(n/p,m/p)*C(n%p,m%p))%p;
}
int main(){
    cin>>T;
    while(T){
    ll n,m;
    T--;
    cin>>n>>m>>p;
    f[0]=1;
    for(int i=1;i<=p;i++)f[i]=f[i-1]*i%p;
    cout<<Luc(n+m,m)<<endl;}
    return 0;
}

组合数

数论



【模板】ST表

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=100000+999;
int read(){
    int f=1,an=0;
    char ch=getchar();
    while(!(‘0‘<=ch&&ch<=‘9‘)){if(ch==‘-‘)f=-f;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+(ch-‘0‘);ch=getchar();}
    return an*f;
}
int x,y,n,m;
struct saber{
int l,r,M;
}tr[maxn*4+999];
int a[maxn];
void build(int k,int l,int r){
    int mid=(l+r)>>1;
    tr[k].l=l;tr[k].r=r;
    if(l==r){tr[k].M=a[l];return;}
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    tr[k].M=max(tr[k<<1].M,tr[k<<1|1].M);
}
int ask(int k,int i,int j){
    int l=tr[k].l,r=tr[k].r;
    if(l==i&&j==r){
        return tr[k].M;}
    int mid=(l+r)>>1;
    if(j<=mid){return ask(k<<1,i,j);}
    else if(i>mid){return ask(k<<1|1,i,j);}
    else {return max(ask(k<<1,i,mid),ask(k<<1|1,mid+1,j));}
}
int main(){
    n=read();m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    build(1,1,n);
    for(int i=1;i<=m;i++){
        x=read();y=read();
        printf("%d\n",ask(1,x,y));
    }
    return 0;
}

线段树

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
const int maxn=1e5+2333;
inline int read(){
    int an=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(‘0‘<=ch&&ch<=‘9‘){an=an*10+ch-‘0‘;ch=getchar();}
    return an*f;
}
int st[maxn][20],n,q;
int main(){
    ios::sync_with_stdio(0);
    n=read();q=read();
    for(int i=1;i<=n;i++)st[i][0]=read();
    for(int j=1;j<=20;j++)
    for(int i=1;i+(1<<j-1)-1<=n;i++)
    st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
    while(q){q--;
        int l=read(),r=read();
        int k=log2(r-l+1);
        cout<<max(st[l][k],st[r-(1<<k)+1][k])<<"\n";
    }
    return 0;
}

st



【模板】矩阵快速幂

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long ll;
using namespace std;

ll n,m,i,j,k;

struct Matrix{
    ll a[105][105];
    inline Matrix operator *(const Matrix &b)const
    {
        Matrix ret;
        for (ll i=1;i<=n;i++)
            for (ll j=1;j<=n;j++)
            {
                ret.a[i][j]=0;
                for (ll k=1;k<=n;k++)
                    ret.a[i][j]+=a[i][k]*b.a[k][j],ret.a[i][j]%=1000000007;
            }
        return ret;
    }
}a;

inline ll read()
{
    ll iep=1,ret=0;char ch=getchar();
    while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) iep=-1;ch=getchar();}
    while (ch>=‘0‘&&ch<=‘9‘){ret=ret*10+ch-‘0‘;ch=getchar();}
    return ret*iep;
}

Matrix ksm(Matrix a,ll x)
{
    Matrix ret,k;k=a;
    ret=a;x--;
    for (;x;x>>=1,k=k*k)
        if (x&1) ret=ret*k;
    return ret;
}

int main()
{
    n=read();k=read();
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
            a.a[i][j]=read();
    a=ksm(a,k);
    for (i=1;i<=n;i++)
    {
        for (j=1;j<n;j++) printf("%d ",a.a[i][j]);
        printf("%d\n",a.a[i][n]);
    }
}

QAQ

想当初不会啊

时间: 2024-10-02 19:30:38

noip2017酱油记前篇的相关文章

Noip2017酱油记(自我吐槽版)

Day0: 对于即将迎来的比赛,大佬门都胸有成竹,一点都不慌张,有着一股“独立于寒风中而巍然不动”的气概,而我这个蒟蒻就只能躲在角落里瑟瑟发抖,天啊,明天就比赛了,好紧张怎么办>_< Day1: 对于今天,一句话总结:OI生涯一场空,小学奥数见祖宗.T1一道小学奥数题,然后一半人挂了......幸亏及时抱住Five20的大腿_(:з」∠)_(之前就听他讲了类似的做法),所以蒟蒻总算沒挂.天,Five20大佬连题目都没看就瞄了一眼数据就直接打出来了O.O......可怕...... Day2:

THUSC2014酱油记

Day0: 坐飞机到北京,然后报到...跟jason_yu分到一个房间,刚好可以蹭点RP.发现房间460RMB/晚,但再带一份早餐就500RMB,难道早餐是40RMB么...在一家川菜馆吃的午晚餐,感觉不怎么样.听说Symen考的还行?又听说PKU总共去了50+个人,一本都要签20+个人?顿感Symen稳了. 晚上zcwwzdjn和leo来探望,说了几句就完了. Day1: 上午弄了个开幕式和合影.看到yangff大号来补报到,大号一来,我们这些小号立刻就加上了Buff.先照了张相,感觉还可以,

NOIP2014酱油记

尘埃落定,来补一下酱油记吧... day-1 晚上老师说有xyz的noip模拟赛,于是果断请假来做(shou)题(nve),题目真是理(S)性(X)愉(B)悦(K),然后就爆零了!感觉noip要爆零滚粗了... day0 上午不想上课,继续来机房做jc的模拟赛,t3比较良心?t1和t2乱搞才拿了40分T_T,怎么都是要滚粗的节奏... 中午启程,在路上翻了翻紫书,发现有些题居然现在还不能一眼秒... 晚上高二+高三一群人在宾馆看异次元的狙击手,我因为不(kan)想(guo)所以在苦逼的翻紫书.睡

ZJOI2018酱油记

ZJOI2018酱油记 前言 作为\(HN\)高一蒟蒻选手,毕竟去了趟\(ZJOI\)玩泥巴 不写点游记还是不太好吧. 今天来补一补. Day0 星期天,中午,我们一群人滚到了学校门口 然后集合,滚去坐地铁连校车都不提供,差评 高铁站感觉很久很久很久没有来过了 换句话说,我很久很久很久没有离开过长沙了 忽然出去一趟,似乎也挺爽的. 在车上,拿出电脑打了几句红警,一个人玩好无聊 然后在车厢里漫无目的的游走,顺便%%%雅礼的巨佬们 下午到了衢州, 跟长沙一比较, 长沙果然是省会城市啊,光是看一眼就能

【Linux】数据流重导向(前篇)

数据流重导向 (redirect) 由字面上的意思来看,好像就是将『数据给他传导到其他地方去』的样子? 没错-数据流重导向就是将某个命令运行后应该要出现在屏幕上的数据, 给他传输到其他的地方,例如文件或者是装置 (例如打印机之类的)!这玩意儿在 Linux 的文本模式底下可重要的! 尤其是如果我们想要将某些数据储存下来时,就更有用了! 1)什么是数据流重导向? 什么是数据流重导向啊?这得要由命令的运行结果谈起!一般来说,如果你要运行一个命令,通常他会是这样的: 我们运行一个命令的时候,这个命令可

THUSC2017酱油记

啊..酱油记三连发.. 果然SHTSC用掉太多RP了.. 其实感觉没什么好写的..都被考懵逼了.. 但还是写一下吧.. DAY0 月考完提前一天到了..什么也没发生 DAY1 先考试再开幕式..好奇怪的设定.. 拿了块胸牌..发了件衣服和一个包..这估计就是这两天最大的收获吧 试机的时候不会用终端的蒟蒻一脸懵逼..一顿瞎搞然后终于会了..没有guide还是各种不适应啊.. 正式考试的时候跑到试机的教室去了..场面一度非常尴尬.. T1类似是在一个矩阵里求一个符合一些奇怪要求的联通的一块?总之暴力

CTSC2015 酱油记

终于又到写酱油记的时间了...不过开心不起来诶.. Day 0 晚上睡不着觉也不造为啥... 起来看了一本亚里亚小说,继续睡,睡不着... 又起来看了一本亚里亚小说,继续睡,睡不着... 然后...死循环了... Day 1 折腾到早上四点才睡着...亚里亚小说都要看完了...早上六点就起来赶第一班高铁去北京 这尼玛...京沪高铁的列车上没有插头...还好我电脑续航能力久...随手找了三道题在车上写掉,然后..补觉补觉! 下午到了人大(旁的燕山宾馆的公寓楼)...这这这...说好的四星级呢...

医疗时鲜资讯:医疗行业未来的变革(续前篇)

背景: 上周参加完展会后,有感而发,将以往自己所阅读的或者了解的关于目前医疗行业的部分时鲜资讯进行了总结分析.尤其是文末猜测了未来可能会发生变革的几大方向,最近在健康界等医疗热门媒体中又发现了与自己想法类似的文章,此处就不强调谁资浅资厚,不争论谁先谁后,仅就未来医疗行业的发展趋势,继续啰嗦几句. 医疗变革: 全科医生培训: 深圳商报的吴江[1]在"'家庭医生'服务实至名归还差什么?"一文中提到了家庭医生服务的概念.文中也提到了,在国外"'全科医生'其实就是'家庭医生'&quo

WC2015酱油记

这是真·酱油记! Day0 因为我们在上海,所以只要坐高铁就可以了2333.到了火车站以后我们坐大巴到学军中学恩,结果坐大巴的时间和做坐高铁的时间差不做←_←. 吐槽了一下住宿环境和课程表就已经晚上了...学军的开幕式表演还是不错哒!但是杜某德的发言显然毁坏了气氛.10点熄灯,但是怎么可以不颓废呢!!!继续补番,寒蝉寒蝉=w= Day1 早上是徐寅展讲课,xyz好帅啊好帅啊好帅啊.先讲toptree的构建,我竟然听懂了toptree是什么东西!!!然后讲merge操作的时候各种感觉不对,明显可能