ST表
P3865

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int Max[100100][21],Log2[100100];
int readd(){
    int ret=0;
    char ch=getchar();
    while('0'<=ch&&'9'>=ch){
        ret*=10;
        ret+=(ch-'0');
        ch=getchar();
    }
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    int n,q,sj;
    n=readd();q=readd();
    sj=int(log2(n));
    for(int i=1;i<=n;i++)
        Max[i][0]=readd();
    for(int i=1;i<=n;i++)
        Log2[i]=(int)log2(i);
    for(int i=1;i<=sj;i++){
        for(int j=1;j+(1<<i)<=n+1;j++){
            Max[j][i]=max(Max[j][i-1],Max[j+(1<<(i-1))][i-1]);
            //cout<<Max[j][i]<<' ';
        }
        //cout<<endl;
    }
    int l,r;
    for(int i=0;i<q;i++){
        l=readd();
        r=readd();
        printf("%d\n",max(Max[l][Log2[r-l+1]],Max[r-(1<<Log2[r-l+1])+1][Log2[r-l+1]]));
    }
    return 0;
}

线性求逆元
3805

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char y[52000100],a[102000100];
int b[52000100];
int main(){
    int ans=0;
    scanf("%s",y);
    int olen=strlen(y),len;
    a[0]='#';a[1]='#';
    for(register int i=0;i<olen;i++){
        a[(i<<1)+2]=y[i];
        a[(i<<1)+3]='#';
    }
    len=strlen(a);
    int maxr=0,mid=0;b[0]=1;
    for(register int i=1;i<=len;i++){
        if(i<maxr)
            b[i]=min(b[(mid<<1)-i],b[mid]+mid-i);
        else
            b[i]=1;
        for(;a[i-b[i]]==a[i+b[i]];b[i]++);
        if(b[i]+i>maxr){
            maxr=i+b[i];
            mid=i;
        }
        ans=max(b[i],ans);
    }
    cout<<ans-1;
    return 0;
}

3811

#include<iostream>
#include<cstdio>
using namespace std;
long long a[3000005];
int main()
{
    int n,p;
    cin>>n>>p;
    a[1]=1;
    if(n>=1)printf("1\n");
    for(register int i=2;i<=n;i++){
        a[i]=(-((p/i)*(a[p%i]))%p+p)%p;
        printf("%lld\n",a[i]);
    }
    return 0;
}

线段树
3372

#include<iostream>
using namespace std;
#define ll long long
ll data[100005];
struct point{
    ll sum;
    ll lazy_tag;
} a[400005];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
void build(int u,int l,int r){
    a[u].lazy_tag=0;
    if(l==r){
        a[u].sum=data[l];
        //cout<<u<<' '<<l<<' '<<r<<' '<<a[u].sum<<endl;
        return;
    }
    int mid=(l+r)>>1;
    build(ls(u),l,mid);
    build(rs(u),mid+1,r);
    a[u].sum=a[ls(u)].sum+a[rs(u)].sum;
    //cout<<u<<' '<<l<<' '<<r<<' '<<a[u].sum<<endl;
}
void push_down(int u,int l,int r){
    if(a[u].lazy_tag==0)
        return;
    a[ls(u)].lazy_tag+=a[u].lazy_tag;
    a[rs(u)].lazy_tag+=a[u].lazy_tag;
    int mid=(l+r)>>1;
    a[ls(u)].sum+=(a[u].lazy_tag*(mid-l+1));
    a[rs(u)].sum+=(a[u].lazy_tag*(r-mid));
    a[u].lazy_tag=0;
}
void add(int u,int al,int ar,int l,int r,int k){//l&r 所在区间 
    if(al<=l&&ar>=r){
        a[u].lazy_tag+=k;
        a[u].sum+=(k*(r-l+1));
        return;
    }
    int mid=(l+r)>>1;
    if(mid>=al){
        push_down(u,l,r);
        add(ls(u),al,ar,l,mid,k);
    }
    if(mid<ar){
        push_down(u,l,r);
        add(rs(u),al,ar,mid+1,r,k);
    }
    a[u].sum=a[ls(u)].sum+a[rs(u)].sum;
}
long long query(int u,int al,int ar,int l,int r){//和 
    //cout<<u<<' '<<al<<' '<<ar<<' '<<l<<' '<<r<<' '<<endl; 
    if(al>r||ar<l)
        return 0ll;
    if(al<=l&&ar>=r){
        //cout<<u<<" get:"<<a[u].sum<<endl;
        return a[u].sum;
    }
    long long ret=0;
    int mid=(l+r)>>1;
    if(mid>=al){
        push_down(u,l,r);
        ret+=query(ls(u),al,ar,l,mid);
    }
    if(mid<ar){
        push_down(u,l,r);
        ret+=query(rs(u),al,ar,mid+1,r);
    }
    //cout<<u<<" get:"<<ret<<endl;
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    int n,m,opt,x,y,z;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>data[i];
    build(1,1,n);
    for(int i=0;i<m;i++){
        cin>>opt;
        if(opt==1){
            cin>>x>>y>>z;
            add(1,x,y,1,n,z);
        }
        else{
            cin>>x>>y;
            cout<<query(1,x,y,1,n)<<endl;
        }
    }
    return 0;
}

3373

#include<iostream>
using namespace std;
#define ll long long
ll mod;
ll data[100005];
struct point{
    ll sum;
    ll addtag;
    ll multag;
} a[400005];
inline int ls(int x){return x<<1;}
inline int rs(int x){return (x<<1)+1;}
void up(int root){
    a[root].sum=(a[ls(root)].sum+a[rs(root)].sum)%mod;
}
void build(int root,int l,int r){
    a[root].addtag=0;
    a[root].multag=1;
    if(l==r)
        a[root].sum=data[l];
    else{
        int mid=(l+r)>>1;
        build(ls(root),l,mid);
        build(rs(root),mid+1,r);
        up(root);
    }
}
void pd(int root,int l,int r){
    int mid=(r+l)>>1;
    a[ls(root)].addtag*=a[root].multag;
    a[rs(root)].addtag*=a[root].multag;
    a[ls(root)].addtag+=a[root].addtag;
    a[rs(root)].addtag+=a[root].addtag;
    a[ls(root)].addtag%=mod;
    a[rs(root)].addtag%=mod;
    a[ls(root)].multag*=a[root].multag;
    a[rs(root)].multag*=a[root].multag;
    a[ls(root)].multag%=mod;
    a[rs(root)].multag%=mod;
    a[ls(root)].sum=a[ls(root)].sum*a[root].multag+a[root].addtag*(mid-l+1);
    a[rs(root)].sum=a[rs(root)].sum*a[root].multag+a[root].addtag*(r-mid);
    a[ls(root)].sum%=mod;
    a[rs(root)].sum%=mod;
    a[root].addtag=0;
    a[root].multag=1;
}
void add(int root,int l,int r,int ql,int qr,ll x){
    if(ql<=l&&qr>=r){
        a[root].addtag+=x;
        a[root].addtag%=mod;
        a[root].sum+=(r-l+1)*x;
        a[root].sum%=mod;
        return;
    }
    if(r<ql||l>qr)
        return;
    int mid=(l+r)>>1;
    pd(root,l,r);
    if(ql<=mid)add(ls(root),l,mid,ql,qr,x);
    if(qr>mid)add(rs(root),mid+1,r,ql,qr,x);
    up(root);
    return;
}
void mul(int root,int l,int r,int ql,int qr,ll x){
    if(ql<=l&&qr>=r){
        a[root].addtag*=x;
        a[root].addtag%=mod;
        a[root].multag*=x;
        a[root].multag%=mod;
        a[root].sum*=x;
        a[root].sum%=mod;
        return;
    }
    if(r<ql||l>qr)
        return;
    int mid=(l+r)>>1;
    pd(root,l,r);
    if(ql<=mid)mul(ls(root),l,mid,ql,qr,x);
    if(qr>mid)mul(rs(root),mid+1,r,ql,qr,x);
    up(root);
    return;
}
ll query(int root,int l,int r,int ql,int qr){
    if(ql<=l&&qr>=r)
        return a[root].sum%mod;
    if(r<ql||l>qr)
        return 0;
    int mid=(l+r)>>1;
    ll ret=0;
    pd(root,l,r);
    if(ql<=mid)ret+=query(ls(root),l,mid,ql,qr);
    if(qr>mid)ret+=query(rs(root),mid+1,r,ql,qr);
    return ret%mod;
}
int main()
{
    ios::sync_with_stdio(false);
    ll n,m,opt,x,y,z;
    cin>>n>>m>>mod;
    for(int i=1;i<=n;i++)cin>>data[i];
    build(1,1,n);
    for(int i=0;i<m;i++){cin>>opt;
        if(opt==1){cin>>x>>y>>z;mul(1,1,n,x,y,z);}
        if(opt==2){cin>>x>>y>>z;add(1,1,n,x,y,z);}
        if(opt==3){cin>>x>>y;cout<<query(1,1,n,x,y)<<endl;}
    }
    return 0;
}

树链剖分

#include<iostream>
#define ll long long
#define MAXN 100005
using namespace std;
ll p;
int cnt=0;
struct edge{
    int v,next;
} g[2*MAXN];
int head[MAXN],ov[MAXN],val[MAXN],depth[MAXN],fa[MAXN],siz[MAXN];
int son[MAXN],id[MAXN],top[MAXN];
using namespace std;
struct point{
    ll sum,tag;
} a[400005];
ll data[100005];
int ls(int root){return root<<1;}
int rs(int root){return (root<<1)+1;}
void up(int root){
    a[root].sum=a[ls(root)].sum+a[rs(root)].sum;
}
void build(int root,int l,int r){
    a[root].tag=0;
    if(l==r)a[root].sum=val[l];
    else{
        int mid=(l+r)>>1;
        build(ls(root),l,mid);
        build(rs(root),mid+1,r);
        up(root);
    }
}
void pd(int root,int l,int r){
    a[ls(root)].tag+=a[root].tag;
    a[ls(root)].tag%=p;
    a[rs(root)].tag+=a[root].tag;
    a[rs(root)].tag%=p;
    int mid=(l+r)>>1;
    a[ls(root)].sum+=a[root].tag*(mid-l+1);
    a[ls(root)].sum%=p;
    a[rs(root)].sum+=a[root].tag*(r-mid);
    a[rs(root)].sum%=p;
    a[root].tag=0;
}
void add(int root,int l,int r,int ql,int qr,ll k){
    if(ql>qr)swap(ql,qr);
    k%=p;
    if(ql<=l&&qr>=r){
        a[root].tag+=k;a[root].sum+=k*(r-l+1);
        return;
    }
    pd(root,l,r);
    int mid=(l+r)>>1;
    if(mid>=ql)add(ls(root),l,mid,ql,qr,k);
    if(qr>mid) add(rs(root),mid+1,r,ql,qr,k);
    up(root);
}
ll query(int root,int l,int r,int ql,int qr){
    if(ql>qr)swap(ql,qr);
    if(ql<=l&&qr>=r){
        return a[root].sum;
    }
    pd(root,l,r);
    int mid=(l+r)>>1;
    ll ret=0;
    if(mid>=ql)ret+=query(ls(root),l,mid,ql,qr);
    if(qr>mid) ret+=query(rs(root),mid+1,r,ql,qr);
    up(root);
    return ret%p;
}
void addedge(int u,int v){
    cnt++;
    g[cnt].v=v;
    g[cnt].next=head[u];
    head[u]=cnt;
}
void dfs1(int n,int f,int deep){
    depth[n]=deep;
    fa[n]=f;
    siz[n]=1;
    if(g[head[n]].v==f&&g[head[n]].next==0){
        son[n]=n;
        return;
    }
    int maxx=0;
    for(int i=head[n];i;i=g[i].next){
        if(g[i].v==f)continue;
        dfs1(g[i].v,n,deep+1);
        siz[n]+=siz[g[i].v];
        maxx=(siz[g[i].v]>siz[maxx])?g[i].v:maxx;
    }
    son[n]=maxx;
}
void dfs2(int n,int htop){
    cnt++;
    id[n]=cnt;
    val[cnt]=ov[n];
    top[n]=htop;
    if(g[head[n]].v==fa[n]&&g[head[n]].next==0)return;
    dfs2(son[n],htop);
    for(int i=head[n];i;i=g[i].next){
        if(g[i].v==fa[n]||g[i].v==son[n])continue;
        dfs2(g[i].v,g[i].v);
    }
}
ll querychain(int x,int y,int n){
    ll ans=0;
    while(top[x]!=top[y]){
        if(depth[top[x]]<depth[top[y]])swap(x,y);
        ans+=query(1,1,n,id[x],id[top[x]]);
        ans%=p;
        x=fa[top[x]];
    }
    ans+=query(1,1,n,id[x],id[y]);
    ans%=p;
    return ans;
}
void addchain(int x,int y,int n,ll k){
    k%=p;
    while(top[x]!=top[y]){
        if(depth[top[x]]<depth[top[y]])swap(x,y);
        add(1,1,n,id[x],id[top[x]],k);
        x=fa[top[x]];
    }
    if(depth[top[x]]<depth[top[y]])swap(x,y);
    add(1,1,n,id[x],id[y],k);
}
ll querytree(int x,int n){
    return query(1,1,n,id[x],id[x]+siz[x]-1);
}
void addtree(int x,int n,ll k){
    add(1,1,n,id[x],id[x]+siz[x]-1,k);
}
int main()
{
    ios::sync_with_stdio(false);
    int n,m,r,u,v;
    cin>>n>>m>>r>>p;
    for(int i=1;i<=n;i++)cin>>ov[i];
    for(int i=1;i<n;i++){
        cin>>u>>v;
        addedge(u,v);
        addedge(v,u);
    }
    dfs1(r,0,1);
    cnt=0;
    dfs2(r,r);
    build(1,1,n);
    int opt,x,y,z;
    for(int i=0;i<m;i++){
        cin>>opt;
        if(opt==1){
            cin>>x>>y>>z;
            addchain(x,y,n,z);
        }
        else if(opt==2){
            cin>>x>>y;
            cout<<querychain(x,y,n)<<endl;
        }
        else if(opt==3){
            cin>>x>>y;
            addtree(x,n,y);
        }
        else if(opt==4){
            cin>>x;
            cout<<querytree(x,n)<<endl;
        }
    }
    return 0;
}

树状数组

#include<iostream>
using namespace std;
typedef long long ll;
ll b[500005],c[500005];
int n;
inline ll lowbit(ll x){return x&(-x);}
void add(int t,ll x){
    while(t<=n){
        c[t]+=x;
        t+=lowbit(t);
    }
}
ll sum(ll t){
    ll ret=0;
    while(t>0){
        ret+=c[t];
        t-=lowbit(t);
    }
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    int m,x,y,k,opt;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>c[i];
        b[i]=c[i]-c[i-1];
    }
    for(int i=1;i<=n;i++)c[i]=0;
    for(int i=1;i<=n;i++)add(i,b[i]);
    for(int i=0;i<m;i++){
        cin>>opt;
        if(opt==1){
            cin>>x>>y>>k;
            add(x,k);
            add(y+1,-k);
        }
        else{
            cin>>x;
            cout<<sum(x)<<endl;
        }
    }
    return 0;
}

3374

#include<iostream>
#define ll long long
using namespace std;
ll n;
ll c[500005];
inline ll lowbit(ll x){
    return x&(-x);
}
void add(ll t,ll x){
    while(t<=n){
        c[t]+=x;
        t+=lowbit(t);
    }
}
ll sum(ll t){
    ll ret=0;
    while(t>0){
        ret+=c[t];
        t-=lowbit(t);
    }
    return ret;
}
ll search(ll l,ll r){
    return sum(r)-sum(l-1);
}
int main()
{
    ios::sync_with_stdio(false);
    ll m,x,y,z;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>x;
        add(i,x);
    }
    for(int i=0;i<m;i++){
        cin>>x>>y>>z;
        if(x==1)
            add(y,z);
        else
            cout<<search(y,z)<<endl;
    }
    return 0;
}

网络流

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define MAXN 100005
using namespace std;
struct fhq_treap{
    int val[MAXN],son[MAXN][2],rnd[MAXN],siz[MAXN],rt,cnt;
    void pushup(int root){
        siz[root]=siz[son[root][0]]+siz[son[root][1]]+1;
    }
    int newnode(int v){
        val[++cnt]=v;
        rnd[cnt]=rand();
        siz[cnt]=1;
        return cnt;
    }
    int merge(int x,int y){
        if(!x||!y)return x+y;
        if(rnd[x]<rnd[y]){
            son[x][1]=merge(son[x][1],y);
            pushup(x);
            return x;
        }
        else{
            son[y][0]=merge(x,son[y][0]);
            pushup(y);
            return y;
        }
    }
    void split(int root,int pos,int &x,int &y){
        if(!root)x=y=0;
        else{
            if(val[root]<=pos){
                x=root;
                split(son[root][1],pos,son[root][1],y);
            }
            else{
                y=root;
                split(son[root][0],pos,x,son[root][0]);
            }
            pushup(root);
        }
    }
    void insert(int v){
        int x,y;
        split(rt,v,x,y);
        rt=merge(merge(x,newnode(v)),y);
    }
    void del(int v){
        int x,y,z;
        split(rt,v,x,z);
        split(x,v-1,x,y);
        y=merge(son[y][0],son[y][1]);
        rt=merge(merge(x,y),z);
    }
    int get_rank(int v){
        int x,y,ret;
        split(rt,v-1,x,y);
        ret=siz[x]+1;
        rt=merge(x,y);
        return ret;
    }
    int get_kth(int root,int k){
        while(1){
            if(k<=siz[son[root][0]])
                root=son[root][0];
            else if(k==siz[son[root][0]]+1)
                return val[root];
            else{
                k-=(siz[son[root][0]]+1);
                root=son[root][1];
            }
        }
    }
    int pre(int v){
        int x,y,ret;
        split(rt,v-1,x,y);
        ret=get_kth(x,siz[x]);
        rt=merge(x,y);
        return ret;
    }
    int suf(int v){
        int x,y,ret;
        split(rt,v,x,y);
        ret=get_kth(y,1);
        rt=merge(x,y);
        return ret;
    }
}T;
int main(){
    int n,x,opt;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>opt>>x;
        if(opt==1)T.insert(x);
        else if(opt==2)T.del(x);
        else if(opt==3)cout<<T.get_rank(x)<<endl;
        else if(opt==4)cout<<T.get_kth(T.rt,x)<<endl;
        else if(opt==5)cout<<T.pre(x)<<endl;
        else if(opt==6)cout<<T.suf(x)<<endl;
    }
    return 0;
}

当前弧优化3376

#include<iostream>
#include<cstring>
#define inf 2147483647
using namespace std;
struct edge{
    int val,to,next;
}a[200005];
int head[10005],q[10005],floor[10005],cnt=0;
bool vis[10005];
void add_edge(int u,int v,int val){
    cnt++;a[cnt].to=v;a[cnt].val=val;a[cnt].next=head[u];head[u]=cnt;}
bool bfs(int s,int t){
    memset(vis,0,sizeof(vis));
    memset(floor,0,sizeof(floor));
    int h=0,ta=1,x;
    q[0]=s;floor[s]=1;vis[s]=1;
    while(h<ta){
        x=q[h];
        for(int i=head[x];i;i=a[i].next){
            if(!vis[a[i].to]&&a[i].val){
                q[ta++]=a[i].to;
                floor[a[i].to]=floor[x]+1;
                vis[a[i].to]=1;
            }
        }
        h++;
    }
    return vis[t];
}
int dfs(int u,int limit,int t){
    if(u==t)return limit;
    int temp,ans=0;
    for(int i=head[u];i&&limit;i=a[i].next){
        if(a[i].val&&floor[u]+1==floor[a[i].to]){
            temp=dfs(a[i].to,min(limit,a[i].val),t);
            if(temp!=-1){
                ans+=temp;
                a[i].val-=temp;
                a[(i^1)+2].val+=temp;
                limit-=temp;
            }
        }
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    int n,m,u,v,w,s,t,ans=0;
    cin>>n>>m>>s>>t;
    for(int i=0;i<m;i++){
        cin>>u>>v>>w;
        add_edge(u,v,w);add_edge(v,u,0);}
    while(bfs(s,t)){
        ans+=dfs(s,inf,t);
    }
    cout<<ans;
    return 0;
}


最小生成树 :
p3366

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int bcj[200005];
int fa(int x)
{
    if(bcj[x]==0)
        return x;
    else{
        int temp=fa(bcj[x]);
        bcj[x]=temp;
        return temp;
    }
}
void merge(int x,int y)
{
    int fx=fa(x),fy=fa(y);
    if(fx!=fy)
        bcj[fy]=fx;
}
bool find(int x,int y)
{
    int fx=fa(x),fy=fa(y);
    if(fx==fy)    
        return true;
    return false;
}
struct edge{
    int val;
    int l,r;
} a[200005];
bool operator<(edge a,edge b){
    return a.val<b.val;
}
int main()
{
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)
        cin>>a[i].l>>a[i].r>>a[i].val;
    sort(a,a+m);
    int cnt=0,ans=0;
    for(int i=0;cnt<n-1;i++){
        if(!find(a[i].l,a[i].r)){
            ans+=a[i].val;
            cnt++;
            merge(a[i].l,a[i].r);
        }
        if(i==m-1&&cnt<n-1){
            cout<<"orz";
            return 0;
        }
    }
    cout<<ans;
    return 0;
}

匈牙利算法
3386

#include<iostream>
#include<cstring>
using namespace std;
bool map[1005][1005],used[1005];
int book[1005];
int n;
bool dfs(int x){
    for(int i=1;i<=n;i++){
        if(map[x][i]==1&&used[i]==false){
            used[i]=1;
            if(book[i]==0||dfs(book[i])){
                book[i]=x;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    int m,e,x,y,ans=0;
    cin>>n>>m>>e;
    for(int i=0;i<e;i++){
        cin>>x>>y;
        if(x<=n&&y<=m)
            map[x][y]=1;
    }
    for(int i=1;i<=m;i++){
        memset(used,0,sizeof(used));
        if(dfs(i))
            ans++;
    }
    cout<<ans;
    return 0;
}

fhqtreap实现的区间翻转
3391

#include<iostream>
#include<cstdlib>
#define MAXN 100005
using namespace std;
struct fhqtreap{
    int rnd[MAXN],siz[MAXN],ch[MAXN][2],val[MAXN],root,cnt;
    bool rev[MAXN];
    void pushup(int rt){
        siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+1;
    }
    int newnode(int v){
        siz[++cnt]=1;
        rnd[cnt]=rand();
        val[cnt]=v;
        return cnt;
    }
    void pushdown(int rt){
        if(rev[rt]){
            swap(ch[rt][0],ch[rt][1]);
            if(ch[rt][0])rev[ch[rt][0]]^=1;
            if(ch[rt][1])rev[ch[rt][1]]^=1;
            rev[rt]=0;
        }
    }
    int merge(int x,int y){
        if(!x||!y)return x+y;
        if(rnd[x]<rnd[y]){
            pushdown(x);
            ch[x][1]=merge(ch[x][1],y);
            pushup(x);
            return x;
        }
        else{
            pushdown(y);
            ch[y][0]=merge(x,ch[y][0]);
            pushup(y);
            return y;
        }
    }
    void split(int rt,int pos,int &x,int &y){
        if(!rt)x=y=0;
        else{
            pushdown(rt);
            if(pos<=siz[ch[rt][0]]){
                //cout<<"进入左子树,pos="<<pos<<endl;
                y=rt;
                split(ch[rt][0],pos,x,ch[rt][0]);
            }
            else{
                //cout<<"进入右子树,pos="<<pos-siz[ch[rt][0]]-1<<endl;
                x=rt;
                split(ch[rt][1],pos-siz[ch[rt][0]]-1,ch[rt][1],y);
            }
            pushup(rt);
        }
    }
    void reverse(int l,int r){
        int x,y,z;
        //cout<<"开始split,pos="<<l-1<<endl;
        split(root,l-1,x,y);
        //cout<<"开始split,pos="<<r-l+1<<endl;
        split(y,r-l+1,y,z);
        rev[y]^=1;
        root=merge(x,merge(y,z));
    }
    void putout(int rt){
        if(!rt)return;
        pushdown(rt);
        putout(ch[rt][0]);
        cout<<rt<<' ';
        putout(ch[rt][1]);
    }
}T;
int main(){
    int n,m,l,r;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        T.root=T.merge(T.root,T.newnode(i));
    for(int i=0;i<m;i++){
        cin>>l>>r;
        T.reverse(l,r);
    }
    T.putout(T.root);
    cout<<endl;
    return 0;
}

KMP 3375

#include<iostream>
#include<cstring>
using namespace std;
int kmp[1000005];
char a[1000005],b[1000005];
int main(){
    int lena,lenb,x=0;
    cin>>a+1>>b+1;
    lena=strlen(a+1);
    lenb=strlen(b+1);
    for(int i=2;i<=lenb;i++){
        while(x&&b[i]!=b[x+1])
            x=kmp[x];
        if(b[i]==b[x+1])kmp[i]=++x;
    }x=0;
    for(int i=1;i<=lena;i++){
        //cout<<x<<' '<<i<<endl;
        while(x&&a[i]!=b[x+1])
            x=kmp[x];
        if(a[i]==b[x+1])x++;
        if(x==lenb){
            cout<<i-lenb+1<<endl;
            x=kmp[x];
        }
    }
    for(int i=1;i<=lenb;i++)cout<<kmp[i]<<" ";
    return 0;
}

LCA

#include<iostream>
#include<cstdio>
using namespace std;
struct edge{
    int v;int next;
} a[1000010];
int head[500005],depth[500005],lg[500005],fa[500005][30],cnt=0;
inline int read(){
    int x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x;
}
inline void add_edge(int u,int v){
    a[++cnt].v=v;
    a[cnt].next=head[u];
    head[u]=cnt;
}
void dfs(int n,int father){
    depth[n]=depth[father]+1;
    //cout<<"father="<<father<<endl;
    fa[n][0]=father;
    for(int i=1;i<lg[depth[n]];i++){
        fa[n][i]=fa[fa[n][i-1]][i-1];
        //cout<<"fa["<<n<<"]["<<i<<"]="<<fa[n][i]<<" ";
    }
    for(int i=head[n];i;i=a[i].next)
        if(a[i].v!=father)
            dfs(a[i].v,n);
    return;
}
inline int lca(int x,int y){
    if(depth[x]<depth[y])swap(x,y);
    while(depth[x]>depth[y])
        x=fa[x][lg[depth[x]-depth[y]]-1];
    if(x==y)return x;
    for(int i=lg[depth[x]]-1;i>=0;i--){
        if(fa[x][i]==fa[y][i])
            continue;
        else
            x=fa[x][i],y=fa[y][i];
        if(fa[x][0]==fa[y][0])
            return fa[x][0];
    }
}
int main(){
    int n,m,root,u,v;
    scanf("%d%d%d",&n,&m,&root);
    for(register int i=1;i<n;i++){
        u=read();v=read();
        add_edge(u,v);
        add_edge(v,u);
    }
    for(register int i=1;i<=n;i++)
        lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    dfs(root,0);
    //for(int i=1;i<=n;i++)cout<<depth[i]<<' ';cout<<endl;
    for(register int i=0;i<m;i++){
        u=read();v=read();
        printf("%d\n",lca(u,v));
    }
    return 0;
}

凸包极角序

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
struct point{
    double x,y;
} a[300005],LTL,b[300005];
int top=0;
bool toleft(point p,point q,point r){
    return (0<(p.x*q.y-q.x*p.y+q.x*r.y-r.x*q.y+r.x*p.y-p.x*r.y));
}
bool operator<(point a,point b){
    return toleft(LTL,a,b);
}
double dis(point a,point b){
    return sqrt(abs(a.x-b.x)*abs(a.x-b.x)+abs(a.y-b.y)*abs(a.y-b.y));
}
int main(){
    /*point t,tt,ttt;
    t.x=-1;t.y=-2;
    tt.x=tt.y=4;
    ttt.x=0;ttt.y=1;
    cout<<toleft(t,tt,ttt);*/
    int n;
    cin>>n;
    LTL.x=LTL.y=1000000007;
    for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;
    for(int i=1;i<=n;i++)
        if(LTL.y>a[i].y||(LTL.y==a[i].y&&LTL.x>a[i].x))
            LTL=a[i];
    bool bj=0;
    for(int i=1;i<=n;i++){
        if(a[i].x==LTL.x&&a[i].y==LTL.y)bj=1;
        if(bj==1&&i<n)a[i]=a[i+1];
    }
    sort(a+1,a+n);
    //for(int i=1;i<n;i++)cout<<a[i].x<<' '<<a[i].y<<endl;
    b[top++]=LTL;
    for(int i=1;i<n;i++){
        //cout<<"\n--------\n";
        if(top<=1){
            b[top++]=a[i];
            continue;
        }
        while(top>1){
            //cout<<"\n----\n";
            //for(int i=0;i<top;i++)cout<<b[i].x<<' '<<b[i].y<<endl;
            if(!toleft(b[top-2],b[top-1],a[i]))
                top--;
            else break;
        }
        b[top++]=a[i];
    }
    double sum=0;
    //cout<<"\n----ans----\n";
    for(int i=1;i<top;i++){
        sum+=dis(b[i],b[i-1]);
        //cout<<b[i].x<<' '<<b[i].y<<endl;
    }
    sum+=dis(b[top-1],b[0]);
    printf("%.2lf",sum);
    return 0;
}/*
9
0 4
0 1
0 0
1 0
2 1
-2 2
-1 -2
4 -1
4 4
*/

Dijkstra
4779

#include<iostream>
#include<utility>
#include<queue>
#include<cstring>
using namespace std;
struct point{
    int diss;
    int u;
};
point mk(int x,int y){
    point xx;
    xx.diss=x;
    xx.u=y;
    return xx;
}
bool operator<(point a,point b){
    return a.diss>b.diss;
}
priority_queue<point> pq;
vector<pair<int,int> > a[100005];
int dis[100005];
bool book[100005];
void dijkstra(int s){
    while(!pq.empty()){
        s=pq.top().u;
        pq.pop();
        if(book[s])continue;
        book[s]=1;
        //cout<<s<<endl;
        for(int i=0;i<a[s].size();i++){
            if(a[s][i].second+dis[s]<dis[a[s][i].first]&&book[a[s][i].first]==0){
                //cout<<a[s][i].first<<'#'<<endl;
                dis[a[s][i].first]=a[s][i].second+dis[s];
                pq.push(mk(dis[a[s][i].first],a[s][i].first));
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    memset(dis,0x3f,sizeof(dis));
    int n,m,s,x,y,c;
    cin>>n>>m>>s;
    for(int i=0;i<m;i++){
        cin>>x>>y>>c;
        a[x].push_back(make_pair(y,c));
    }
    dis[s]=0;
    pq.push(mk(0,s));
    dijkstra(s);
    for(int i=1;i<=n;i++)cout<<dis[i]<<' ';
    return 0;
}
/*
6 8 3
1 3 3
1 5 3
1 6 3
2 5 1
2 6 1
3 4 3
3 5 3
5 6 3
*/

hhhhhh
1 声望0 粉丝