板子

来源:互联网 发布:淘宝云客服哪个部门好 编辑:程序博客网 时间:2024/04/28 01:11

基本

快读

inline void read(int &n){    n=0;bool b=0;    char c=getchar();    while(c<'0'||c>'9'){c=getchar();if(c=='-')b=1;}    while(c>='0'&&c<='9') n=n*10+c-48,c=getchar();    if(b) n=-n;}

图论

tarjan

//强连通分量void dfs(int now,int fa){    dfn[now]=low[now]=++Time;    instack[now]=1;    s.push(now);    for(int i=head[now];i;i=a[i].nxt)      if(!dfn[a[i].to])      {        dfs(a[i].to,now);        low[now]=min(low[now],low[a[i].to]);      }      else if(instack[a[i].to]) low[now]=min(low[now],dfn[a[i].to]);    if(dfn[now]==low[now])    {        tot++;        int tmp;        do        {            tmp=s.top();            instack[tmp]=0;        }while(tmp!=now);    }}//缩点void dfs(int now){    low[now]=dfn[now]=++Time;    s[++top]=now;    instack[now]=1;    for(int i=head[now];i;i=a[i].nxt)      if(!dfn[a[i].to])      {        dfs(a[i].to);        low[now]=min(low[now],low[a[i].to]);      }      else if(instack[a[i].to]) low[now]=min(low[now],dfn[a[i].to]);    if(low[now]==dfn[now])    {        int tmp;        tot++;        do        {            tmp=s[top--];            instack[tmp]=0;            block[tmp]=tot;            size[tot]++;        }while(tmp!=now);    }}//LCAint find(int n){    if(f[n]!=n) f[n]=find(f[n]);    return f[n];}void dfs(int now,int depth){    f[now]=now;    vis[now]=1;    deep[now]=depth;    for(int i=head[now];i;i=a[i].nxt)      if(!vis[a[i].to])      {        dfs(a[i].to,depth+a[i].dis);        f[a[i].to]=now;      }    for(int i=Head[now];i;i=ask[i].nxt)      if(vis[ask[i].to]) ans[ask[i].id]=deep[now]+deep[ask[i].to]-(deep[find(ask[i].to)]<<1);}

求RMQ

//h==0:取[l,r]的最大值h==1:取[l,r]的最小值 #include<cstdio>#include<cmath>#include<cstring>#define max(a,b) a>b?a:b#define min(a,b) a<b?a:bint n,i,j,l,r,x,h;int a[10001];int f[10001][15];int ff[10001][15];int main(){    scanf("%d",&n);    for(i=1;i<=n;i++)      scanf("%d",&a[i]);    memset(ff,10,sizeof(ff));    for(i=1;i<=n;i++)    {        f[i][0]=a[i];        ff[i][0]=a[i];    }    for(j=1;j<=log(n)/log(2);j++)      for(i=1;i<=n+1-(1<<j);i++)      {        f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);        ff[i][j]=min(ff[i][j-1],ff[i+(1<<(j-1))][j-1]);      }    scanf("%d",&n);    for(i=1;i<=n;i++)    {        scanf("%d%d%d",&h,&l,&r);        x=log(r-l+1)/log(2);        if(h==0) printf("%d\n",max(f[l][x],f[r+1-(1<<x)][x]));        else printf("%d\n",min(ff[l][x],ff[r+1-(1<<x)][x]));    }    return 0;}

网络流

inline bool bfs(int s,int t){    memset(deep,0,sizeof(deep));    q.clear();    q.push(s);    deep[s]=1;    while(!q.empty())    {        int tmp=q.front();        q.pop();        for(int i=head[tmp];i;i=a[i].next)          if(a[i].remain&&!deep[a[i].to]) deep[a[i].to]=deep[tmp]+1,q.push(a[i].to);    }    return deep[t];}int dfs(int now,int t,int limit){    if(now==t) return limit;    int flow=0,f;    for(int i=head[now];i;i=a[i].next)      if(a[i].remain&&deep[a[i].to]==deep[now]+1)      {        f=dfs(a[i].to,t,min(a[i].remain,limit));        a[i].remain-=f;        a[i^1].remain+=f;        limit-=f;        flow+=f;        if(!limit) return flow;      }    deep[now]=-1;    return flow;}inline int dinic(int s,int t){    int ans=0;    while(bfs(s,t)) ans+=dfs(s,t,INF);    return ans;}

费用流

inline bool SPFA(){    memset(dis,10,sizeof(dis));    dis[S]=0;    u[S]=INF;    q.push(S),b[S]=1;    while(!q.empty())    {        int tmp=q.front();q.pop();        for(int i=head[tmp];i;i=a[i].next)          if(dis[a[i].to]>dis[tmp]+a[i].cost&&a[i].remain)          {            f[a[i].to]=tmp;            u[a[i].to]=min(u[tmp],a[i].remain);            dis[a[i].to]=dis[tmp]+a[i].cost;            if(!b[a[i].to]) q.push(a[i].to),b[a[i].to]=1;          }    }    if(dis[T]>INF) return 0;    ll p=T;    while(p!=S)    {        a[f[p]].remain-=u[T];        a[f[p]^1].remain+=u[T];        p=a[f[p]^1].to;    }    ans+=u[T]*dis[T];    return 1;}inline void mcmf(){while(SPFA());}

莫队

#include<bits/stdc++.h>using namespace std;struct node{    int l,r,id;}q[200010];int a[50010];int ans[200010];int pos[200010];int num[1000010];int size,n,m,L=1,R,Ans;inline bool cmp(node a,node b){    if(pos[a.l]==pos[b.l]) return a.r<b.r;    return pos[a.l]<pos[b.l];}int main(){    scanf("%d",&n);    size=sqrt(n);    for(int i=1;i<=n;i++)      scanf("%d",&a[i]),pos[i]=i/size;    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        scanf("%d%d",&q[i].l,&q[i].r);        q[i].id=i;    }    sort(q+1,q+m+1,cmp);    for(int i=1;i<=m;i++)    {        while(L<q[i].l) if(!--num[a[L++]]) Ans--;        while(L>q[i].l) if(!num[a[--L]]++) Ans++;        while(R<q[i].r) if(!num[a[++R]]++) Ans++;        while(R>q[i].r) if(!--num[a[R--]]) Ans--;        ans[q[i].id]=Ans;    }    for(int i=1;i<=m;i++)      printf("%d\n",ans[i]);    return 0;}

分块

#include<cmath>#include<cstdio>#include<algorithm>using namespace std;const int N=1e6+10;struct Block{    int l,r,num,plus;    int a[1010];    inline void keep()    {        sort(a+1,a+num+1);    }    inline int find(int n)    {        int L=1,R=num,mid;        n-=plus;        while(L<R)        {            mid=(L+R)>>1;            if(a[mid]<n) L=mid+1;            else R=mid;        }        return L;    }}a[1010];int s[N];int belong[N];int n,q,x,y,z,ans,block,num;char c;inline void read(int &n){    n=0;char c=getchar();    while(c<'0'||c>'9') c=getchar();    while(c>='0'&&c<='9') n=n*10+c-48,c=getchar();}inline void build(){    block=sqrt(n);    num=n/block;if(n%block) num++;    for(int i=1;i<=num;i++)      a[i].l=(i-1)*block+1,a[i].r=i*block,a[i].num=block;    a[num].r=n;a[num].num=a[num].r-a[num].l+1;    for(int i=1;i<=n;i++)      belong[i]=(i-1)/block+1;    for(int i=1;i<=num;i++)    {        for(int j=a[i].l;j<=a[i].r;j++)          a[i].a[j-a[i].l+1]=s[j];        a[i].keep();    }}inline void add(int x,int y,int z){    if(belong[x]==belong[y])    {        for(int i=x;i<=y;i++)          s[i]+=z;        for(int i=a[belong[x]].l;i<=a[belong[x]].r;i++)          a[belong[x]].a[i-a[belong[x]].l+1]=s[i];        a[belong[x]].keep();        return;    }    for(int i=x;i<=a[belong[x]].r;i++)      s[i]+=z;    for(int i=a[belong[x]].l;i<=a[belong[x]].r;i++)      a[belong[x]].a[i-a[belong[x]].l+1]=s[i];    a[belong[x]].keep();    for(int i=belong[x]+1;i<belong[y];i++)      a[i].plus+=z;    for(int i=a[belong[y]].l;i<=y;i++)      s[i]+=z;    for(int i=a[belong[y]].l;i<=a[belong[y]].r;i++)      a[belong[y]].a[i-a[belong[y]].l+1]=s[i];    a[belong[y]].keep();}inline int ask(int x,int y,int z){    int ans=0;    if(belong[x]==belong[y])    {        for(int i=x;i<=y;i++)          if(s[i]+a[belong[x]].plus>=z) ans++;        return ans;    }    for(int i=x;i<=a[belong[x]].r;i++)      if(s[i]+a[belong[x]].plus>=z) ans++;    for(int i=belong[x]+1;i<belong[y];i++)    {        int p=a[i].find(z);        if(a[i].a[p]+a[i].plus>=z) ans+=a[i].num-p+1;    }    for(int i=a[belong[y]].l;i<=y;i++)      if(s[i]+a[belong[y]].plus>=z) ans++;    return ans;}int main(){    read(n),read(q);    for(int i=1;i<=n;i++)      read(s[i]);    build();    while(q--)    {        c=getchar();        while(c!='A'&&c!='M') c=getchar();        read(x),read(y),read(z);        if(c=='A') printf("%d\n",ask(x,y,z));        else add(x,y,z);    }    return 0;}

数论

Lucas&中国剩余定理&快速幂&扩展欧几里得&逆元

#include<cmath>#include<cstdio>typedef long long ll;const ll M=999911659;ll prime[5]={0,2,3,4679,35617};ll fac[40000];ll inv[40000];ll a[5];ll n,g,ans,x,y;inline ll pow(ll a,ll b,ll p){    ll ans=1;    a%=p;    for(;b;b>>=1,a=1ll*a*a%p)      if(b&1) ans=1ll*ans*a%p;    return ans;}void exgcd(ll a,ll b,ll &x,ll &y){    if(!b) {x=1,y=0;return;}    exgcd(b,a%b,y,x);    y-=(a/b)*x;}inline ll lucas(ll n,ll m,ll p){    ll ans=1;    while(n&&m)    {        ll a=n%p,b=m%p;        if(a<b) return 0;        ans=(1ll*ans*fac[a]*inv[fac[b]]*inv[fac[a-b]])%p;        n/=p,m/=p;    }    return ans;}int main(){    scanf("%lld%lld",&n,&g);    inv[0]=1;fac[0]=1;fac[1]=1;    for(ll i=1;i<=4;i++)    {        for(ll j=1;j<=prime[i];j++)        {            fac[j]=(fac[j-1]*j)%prime[i];            inv[j]=pow(j,prime[i]-2,prime[i]);        }        for(ll j=1;j<=sqrt(n);j++)          if(!(n%j))          {            a[i]=(1ll*a[i]+lucas(n,j,prime[i]))%prime[i];            if(j*j<n) a[i]=(1ll*a[i]+lucas(n,n/j,prime[i]))%prime[i];          }    }    for(ll i=1;i<=4;i++)    {        exgcd((M-1)/prime[i],prime[i],x,y);        ans=(1ll*ans+1ll*a[i]*x*((M-1)/prime[i]))%(M-1);    }    ans=(ans%(M-1)+M-1)%(M-1);    if(!ans) ans=M-1;    printf("%lld",pow(g,ans,M));    return 0;}

扩展中国剩余定理

void exgcd(ll a,ll b,ll &x,ll &y){    if(!b){x=1,y=0;return;}    exgcd(b,a%b,y,x);    y-=(a/b)*x;}inline ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}inline ll inv(ll x,ll y){    ll x1,y1;exgcd(x,y,x1,y1);    return (x1%y+y)%y;}inline bool merge(ll m1,ll r1,ll m2,ll r2,ll &m3,ll &r3){    ll d=gcd(m1,m2),r=r2-r1;    if(r%d) return 0;    r=(r%m2+m2)%m2;    m1/=d,m2/=d;    r=r/d*inv(m1,m2)%m2*m1*d+r1;    m3=m1*m2*d,r3=(r%m3+m3)%m3;    return 1;}inline ll CRT(){    ll m1=m[1],r1=r[1];    for(int i=2;i<=n;i++)    {        ll m2=m[i],r2=r[i],m3,r3;        if(!merge(m1,r1,m2,r2,m3,r3)) return -1;        m1=m3,r1=r3;    }    return (r1%m1+m1)%m1;}

欧拉定理

线性求phi

inline void calc(){    for(int i=1;i<n;i++)      phi[i]=i;    for(int i=2;i<n;i++)    {        if(phi[i]==i)          for(int j=i;j<n;j+=i)            phi[j]=(phi[j]/i)*(i-1);        ans+=phi[i];    }    ans++;}

单点求phi

inline ll phi(ll N){    ll ans=N;    for(int i=2;i<=n;i++)      if(N%i==0)      {        ans=ans/i*(i-1);        while(N%i==0) N/=i;      }    if(N>1) ans=ans/N*(N-1);    return ans;}

线性求逆元

    inv[i]=1ll*(m-m/i)*inv[m%i]%m;

mobius反演&&(线性求mu值)

inline void mobius(){    mu[1]=1;    for(int i=2;i<=100000;i++)    {        if(!Prime[i]) prime[++tot]=i,mu[i]=-1;        for(int j=1;j<=tot&&prime[j]*i<=100000;j++)        {            Prime[prime[j]*i]=1;            if(i%prime[j]==0) break;            mu[prime[j]*i]=-mu[i];        }    }    for(int i=1;i<=100000;i++)    {        f[i].second=i;        for(int j=i;j<=100000;j+=i)          f[j].first+=i;    }    sort(f+1,f+100001);}inline void add(int pos,int num){    for(int i=pos;i<=100000;i+=lowbit(i))      a[i]+=num;}inline int ask(int pos){    int ans=0;    for(int i=pos;i;i-=lowbit(i))      ans+=a[i];    return ans;}inline int solve(int n,int m){    if(n>m) swap(n,m);    int ans=0;    for(int i=1,last;i<=n;i=last+1)    {        last=min(n/(n/i),m/(m/i));        ans+=(ask(last)-ask(i-1))*(n/i)*(m/i);    }    return ans;}

高斯消元

    for(int i=1;i<=n;i++)    {        int p=i;        for(int j=i+1;j<=n;j++)          if(fabs(f[j][i])>fabs(f[p][i])) p=j;        if(p!=i) for(int j=1;j<=n+1;j++)          swap(f[i][j],f[p][j]);        double tmp=f[i][i];        for(int j=1;j<=n+1;j++)          f[i][j]/=tmp;        for(int k=1;k<=n;k++)          if(k!=i)          {            tmp=f[k][i];            for(int j=1;j<=n+1;j++)              f[k][j]-=f[i][j]*tmp;          }    }

FFT

typedef complex<double> cp;const double pi=acos(-1);inline void FFT(cp *a,int f){    for(int i=0;i<n;i++)      if(i<r[i]) swap(a[i],a[r[i]]);    for(int i=1;i<n;i<<=1)    {        cp wn(cos(pi/i),f*sin(pi/i));        for(int j=0,tmp=i<<1;j<n;j+=tmp)        {            cp w(1,0);            for(int k=0;k<i;k++,w*=wn)            {                cp x=a[j+k],y=w*a[j+k+i];                a[j+k]=x+y,a[j+k+i]=x-y;            }        }    }}

bsgs

inline ll bsgs(ll x,ll z,ll p){    ma.clear(),x%=p;    if(!x&&!z) return 0;    if(!x) return -1;    ll m=(ll)ceil(sqrt((double)p)),tmp=1;    ma[1]=m+1;    for(int i=1;i<m;i++)    {        tmp=tmp*x%p;        if(!ma[tmp]) ma[tmp]=i;    }    ll inv=1;tmp=ksm(x,p-m-1,p);    for(ll k=0;k<m;k++)    {        int i=ma[(z*inv)%p];        if(i)        {            if(i==m+1) i=0;            return k*m+i;        }        inv=(inv*tmp)%p;    }    return -1;}

字符串

AC自动机

struct AC{    int ch[26];    int fail,cnt;}a[500001];int n,m,tot;char s[1000001];inline void init(){    q.clear();    for(int i=0;i<=tot;i++)    {        memset(a[i].ch,0,sizeof(a[i].ch));        a[i].cnt=a[i].fail=0;    }    tot=0;    a[0].fail=-1;}inline void insert(char *s){    int now=0,p,len=strlen(s);    for(int i=0;i<len;i++)    {        p=s[i]-'a';        if(!a[now].ch[p]) a[now].ch[p]=++tot;        now=a[now].ch[p];    }    a[now].cnt++;}inline void makefail(){    q.push(0);    while(!q.empty())    {        int now=q.front();        q.pop();        for(int i=0;i<26;i++)          if(a[now].ch[i])          {            int p=a[now].fail;            while(p!=-1&&!a[p].ch[i]) p=a[p].fail;            if(p==-1) a[a[now].ch[i]].fail=0;            else a[a[now].ch[i]].fail=a[p].ch[i];            q.push(a[now].ch[i]);          }    }}inline int find(int now){    int ans=0;    while(now&&a[now].cnt!=-1)    {        ans+=a[now].cnt;        a[now].cnt=-1;        now=a[now].fail;    }    return ans;}inline int ask(char *s){    int ans=0,now=0,len=strlen(s);    for(int i=0;i<len;i++)    {        int p=s[i]-'a';        if(a[now].ch[p]) now=a[now].ch[p];        else        {            int pos=a[now].fail;            while(pos!=-1&&!a[pos].ch[p]) pos=a[pos].fail;            if(pos==-1) now=0;            else now=a[pos].ch[p];        }        ans+=find(now);    }    return ans;}

Fail树

#include<queue>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lowbit(x) x&(-x)const int N=1e5+10;struct AC{    int ch[26];    int fail,fa;}a[N];struct query{    int x,y,id;    bool operator <(const query other)const    {        return y<other.y;    }}q[N];struct edge{    int next,to;}e[N<<1];int t[N],head[N],pos[N];char s[N];int in[N],out[N];int ans[N];int tot,num,n,x,y,Tot,len;inline void add(int x,int y){    e[++num].next=head[x],e[num].to=y,head[x]=num;    e[++num].next=head[y],e[num].to=x,head[y]=num;}inline void build(){    int now=0,num=0;    for(int i=0;i<len;i++)      if(s[i]=='B') now=a[now].fa;      else if(s[i]=='P') pos[++num]=now;      else      {        if(!a[now].ch[s[i]-'a']) a[now].ch[s[i]-'a']=++tot,a[a[now].ch[s[i]-'a']].fa=now;        now=a[now].ch[s[i]-'a'];      }}inline void makefail(){    a[0].fail=-1;    queue<int>Q;    while(!Q.empty()) Q.pop();    for(int i=0;i<26;i++)      if(a[0].ch[i])      {        Q.push(a[0].ch[i]);        add(0,a[0].ch[i]);      }    while(!Q.empty())    {        int tmp=Q.front();Q.pop();        for(int i=0;i<26;i++)        {            if(!a[tmp].ch[i])            {                a[tmp].ch[i]=a[a[tmp].fail].ch[i];                continue;            }            a[a[tmp].ch[i]].fail=a[a[tmp].fail].ch[i];            add(a[a[tmp].fail].ch[i],a[tmp].ch[i]);            Q.push(a[tmp].ch[i]);        }    }}void dfs(int now,int fa){    in[now]=++Tot;    for(int i=head[now];i;i=e[i].next)      if(e[i].to!=fa) dfs(e[i].to,now);    out[now]=Tot;}inline void Add(int now,int num){    for(int i=now;i<=Tot;i+=lowbit(i))      t[i]+=num;}inline int ask(int now){    int ans=0;    for(int i=now;i;i-=lowbit(i))      ans+=t[i];    return ans;}inline void work(){    int now=0,tot=0,j=1;    for(int i=0;i<len;i++)      if(s[i]>='a'&&s[i]<='z')      {        now=a[now].ch[s[i]-'a'];        Add(in[now],1);      }      else if(s[i]=='B')      {        Add(in[now],-1);        now=a[now].fa;      }      else      {        tot++;        for(;q[j].y==tot;j++)          ans[q[j].id]=ask(out[pos[q[j].x]])-ask(in[pos[q[j].x]]-1);      }}int main(){    scanf("%s",s);    len=strlen(s);    build();    makefail();    scanf("%d",&n);    for(int i=1;i<=n;i++)      scanf("%d %d",&q[i].x,&q[i].y),q[i].id=i;    sort(q+1,q+n+1);    dfs(0,-1);    work();    for(int i=1;i<=n;i++)      printf("%d\n",ans[i]);    return 0;}

后缀数组

inline void makesa(){    int *x=t1,*y=t2,m=30;    for(int i=0;i<m;i++) c[i]=0;    for(int i=0;i<n;i++) c[x[i]=s[i]-'a']++;    for(int i=1;i<m;i++) c[i]+=c[i-1];    for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;    for(int k=1;k<=n;k<<=1)    {        int p=0;        for(int i=n-k;i<n;i++) y[p++]=i;        for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;        for(int i=0;i<m;i++) c[i]=0;        for(int i=0;i<n;i++) c[x[y[i]]]++;        for(int i=1;i<m;i++) c[i]+=c[i-1];        for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];        swap(x,y);        p=1;x[sa[0]]=0;        for(int i=1;i<n;i++)          x[sa[i]]=cmp(y,sa[i],sa[i-1],k)?p-1:p++;        if(p>=n) break;        m=p;    }}inline void makeheight(){    for(int i=0;i<n;i++) rank[sa[i]]=i;    int k=0;    for(int i=0;i<n;i++)      if(rank[i])      {        int j=sa[rank[i]-1];        if(k) k--;        while(s[i+k]==s[j+k]) k++;        height[rank[i]]=k;      }}

manacher

    scanf("%d\n",&n);    a[0]='$';    for(int i=1;i<=n;i++)      a[++len]='#',a[++len]=getchar();    a[len+1]=a[len+2]='#';    for(int i=1;i<=len;i++)    {        if(i<mx) p[i]=min(p[pos*2-i],mx-i);        else p[i]=1;        while(a[i-p[i]]==a[i+p[i]]) p[i]++;        if(i+p[i]>mx) mx=i+p[i],pos=i;    }    for(int i=1;i<=len;i++)      if(a[i]=='#') f[i]=i;      else f[i]=i+1;    for(int i=3;i<=len;i+=2)    {        int tmp=i-(p[i]>>1);        if(!tmp) continue;        tmp=find(tmp);        while(tmp+p[tmp]<i&&tmp<i) f[tmp]=find(tmp+1),tmp=f[tmp];        if(tmp<i) ans=max(ans,(i-tmp)<<1);    }

KMP

    scanf("%s%s",a+1,b+1);    l1=strlen(a+1),l2=strlen(b+1);    j=0;    for(i=2;i<=l2;i++)    {        while(j&&b[i]!=b[j+1]) j=next[j];        if(b[i]==b[j+1]) j++;        next[i]=j;    }    j=0;    for(i=1;i<=l1;i++)    {        while(j&&a[i]!=b[j+1]) j=next[j];        if(a[i]==b[j+1]) j++;        if(j==l2)        {            printf("%d\n",i-l2+1);            j=next[j];        }    }

数据结构

LCT

#include<bits/stdc++.h>using namespace std;struct node{    int rev;    node *ch[2],*fa;    inline int getwh()    {        return fa->ch[0]==this?0:1;    }    inline void setch(int wh,node *child);    inline bool isroot();    inline void pushdown()    {        if(rev)        {            node *t=ch[0];ch[0]=ch[1];ch[1]=t;            ch[0]->rev^=1,ch[1]->rev^=1;            rev=0;        }    }}pool[20001],*null;inline void node::setch(int wh,node *child){    ch[wh]=child;    if(child!=null) child->fa=this;}inline bool node::isroot(){    return (fa==null)||(fa->ch[0]!=this&&fa->ch[1]!=this);}char s[10];int n,m,x,y;inline void getstring(){    int p=-1;char c=getchar();    while((c<'a'||c>'z')&&(c<'A'||c>'Z')) c=getchar();    while((c>='a'&&c<='z')||(c>='A'&&c<='Z')) s[++p]=c,c=getchar();}inline void clear(node *now){    now->fa=now->ch[0]=now->ch[1]=null;}inline void rotate(node *now){    node *fa=now->fa,*grand=now->fa->fa;    if(!fa->isroot()) grand->pushdown();    fa->pushdown();now->pushdown();    int wh=now->getwh();    fa->setch(wh,now->ch[wh^1]);    if(fa->isroot()) now->fa=fa->fa;    else grand->setch(fa->getwh(),now);    now->setch(wh^1,fa);}inline void splay(node *now){    if(now->isroot()) return;    for(;!now->isroot();rotate(now))      if(!now->fa->isroot()) now->getwh()==now->fa->getwh()?rotate(now->fa):rotate(now);}inline node *access(node *now){    node *t=null;    for(;now!=null;t=now,now=now->fa)      splay(now),now->pushdown(),now->setch(1,t);    return t;}inline void changeroot(node *now){    access(now)->rev^=1;    splay(now);}inline void connect(node *x,node *y){    changeroot(x);    x->fa=y;    access(x);}inline void del(node *x,node *y){    changeroot(x);    access(y);    splay(x);    x->pushdown();    x->ch[1]=y->fa=null;}inline node *findroot(node *now){    for(now=access(now);now->ch[0]!=null;now->pushdown(),now=now->ch[0]);    return now;}inline bool ask(node *x,node *y){    if(findroot(x)==findroot(y)) return 1;    return 0;}int main(){    null=pool;    null->fa=null->ch[0]=null->ch[1]=null;    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)      clear(pool+i);    while(m--)    {        getstring();        scanf("%d%d",&x,&y);        if(s[0]=='C') connect(pool+x,pool+y);        else if(s[0]=='D') del(pool+x,pool+y);        else if(s[0]=='Q') ask(pool+x,pool+y)?puts("Yes"):puts("No");    }    return 0;}

splay

#include<cstdio>const int INF=2000;inline int max(int a,int b){if(a>=b)return a;return b;}inline int min(int a,int b){if(a<=b)return a;return b;}inline void swap(int &a,int &b){a^=b;b^=a;a^=b;}struct stack{    int t;    int a[500010];    inline void clear(){t=-1;}    inline void push(int &n){a[++t]=n;}    inline int top(){return a[t];}    inline void pop(){t--;}    inline bool empty(){return t<0;}}reuse;struct node{    int num,size,lmax,rmax,maxn,sum,id,rev;    bool change;    node *ch[2],*fa;    inline void update()    {        size=ch[0]->size+ch[1]->size+1;        sum=ch[0]->sum+ch[1]->sum;        if(num!=-INF) sum+=num;        lmax=max(ch[0]->lmax,max(ch[0]->sum+num,ch[0]->sum+ch[1]->lmax+num));        rmax=max(ch[1]->rmax,max(ch[1]->sum+num,ch[1]->sum+ch[0]->rmax+num));        maxn=max(ch[0]->maxn,ch[1]->maxn);        maxn=max(maxn,max(ch[0]->rmax+num,ch[1]->lmax+num));        maxn=max(maxn,max(ch[0]->rmax+ch[1]->lmax+num,num));    }    inline int getwh()    {        if(fa->ch[0]==this) return 0;return 1;    }    inline void pushchange(int n)    {        num=n;        sum=size*n;        maxn=lmax=rmax=max(num,sum);        change=1;    }    inline void pushrev()    {        swap(lmax,rmax);        node *tmp=ch[0];ch[0]=ch[1];ch[1]=tmp;        rev^=1;    }    inline void setch(int wh,node *child);    inline void pushdown();}pool[500010],*root,*null,*newroot;inline void node::setch(int wh,node *child){    ch[wh]=child;    if(child!=null) child->fa=this;    update();}inline void node::pushdown(){    if(rev)    {        if(ch[0]!=null) ch[0]->pushrev();        if(ch[1]!=null) ch[1]->pushrev();        rev=0;    }    if(change)    {        if(ch[0]!=null) ch[0]->pushchange(num);        if(ch[1]!=null) ch[1]->pushchange(num);        change=0;    }}char s[10];int a[500010];int n,m,tot,x,y,z;inline void read(int &n){    n=0;char c=getchar();bool b=0;    while(c<'0'||c>'9'){if(c=='-')b=1;c=getchar();}    while(c>='0'&&c<='9') n=n*10+c-48,c=getchar();    if(b) n*=-1;}inline void getstring(){    int p=-1;    char c=getchar();    while((c<'A'||c>'Z')&&c!='-') c=getchar();    while((c>='A'&&c<='Z')||c=='-') s[++p]=c,c=getchar();}inline node *getnew(int num){    node *now;    if(!reuse.empty()) now=pool+reuse.top(),now->id=reuse.top(),reuse.pop();    else now=pool+ ++tot,now->id=tot;    now->ch[0]=now->ch[1]=now->fa=null;    now->num=now->sum=now->maxn=now->lmax=now->rmax=num;    if(num==-1e9) now->sum=0;    now->size=1;    now->change=now->rev=0;    return now;}inline void rotate(node *now){    node *fa=now->fa,*grand=now->fa->fa;    int wh=now->getwh();    fa->setch(wh,now->ch[wh^1]);    now->setch(wh^1,fa);    now->fa=grand;    if(grand!=null)    {        if(grand->ch[0]==fa) grand->ch[0]=now;        else grand->ch[1]=now;    }}inline void splay(node *now,node *tar){    for(;now->fa!=tar;rotate(now))      if(now->fa->fa!=tar)      {        if(now->getwh()==now->fa->getwh()) rotate(now->fa);        else rotate(now);      }    if(tar==null) root=now;}node *build(int l,int r){    int mid=(l+r)>>1;    node *now=getnew(a[mid]);    if(l<mid) now->setch(0,build(l,mid-1));    if(r>mid) now->setch(1,build(mid+1,r));    return now;}inline node *kth(int rank){    node *now=root;    int ranking=0;    while(now!=null)    {        now->pushdown();        int tmp=ranking+now->ch[0]->size;        if(tmp+1==rank) return now;        if(tmp+1>rank) now=now->ch[0];        else ranking=tmp+1,now=now->ch[1];    }}inline void insert(node *newone,int pos){    splay(kth(pos),null);    splay(kth(pos+1),root);    root->ch[1]->setch(0,newone);    root->update();}void dfs(node *now){    reuse.push(now->id);    if(now->ch[0]!=null) dfs(now->ch[0]);    if(now->ch[1]!=null) dfs(now->ch[1]);}inline void del(int pos,int n){    splay(kth(pos-1),null);    splay(kth(pos+n),root);    dfs(root->ch[1]->ch[0]);    root->ch[1]->setch(0,null);    root->update();}inline void changenum(int pos,int n,int num){    splay(kth(pos-1),null);    splay(kth(pos+n),root);    root->ch[1]->ch[0]->pushchange(num);    root->ch[1]->update();    root->update();}inline void reverse(int pos,int n){    splay(kth(pos-1),null);    splay(kth(pos+n),root);    root->ch[1]->ch[0]->pushrev();    root->ch[1]->update();    root->update();}inline int sum(int pos,int n){    splay(kth(pos-1),null);    splay(kth(pos+n),root);    return root->ch[1]->ch[0]->sum;}int main(){    read(n),read(m);    null=pool;    null->ch[0]=null->ch[1]=null->fa=null;    null->lmax=null->rmax=null->maxn=-INF;    root=null;    reuse.clear();    for(register int i=1;i<=n;i++)      read(a[i]);    a[0]=a[n+1]=-INF;    root=build(0,n+1);    while(m--)    {        getstring();        if(s[0]=='I')        {            read(x),read(y);            for(register int i=1;i<=y;i++)              read(a[i]);            newroot=build(1,y);            insert(newroot,x+1);        }        else if(s[0]=='D') read(x),read(y),del(x+1,y);        else if(s[2]=='K') read(x),read(y),read(z),changenum(x+1,y,z);        else if(s[0]=='R') read(x),read(y),reverse(x+1,y);        else if(s[0]=='G') read(x),read(y),printf("%d\n",sum(x+1,y));        else printf("%d\n",root->maxn);    }    return 0;}

树链剖分

void dfs(int now,int fa,int depth){    deep[now]=depth;    f[now]=fa;    size[now]=1;    int tmp=-INF;    for(int i=head[now];i;i=a[i].next)      if(a[i].to!=fa)      {        dfs(a[i].to,now,depth+1);        size[now]+=size[a[i].to];        if(size[a[i].to]>tmp) tmp=size[a[i].to],son[now]=a[i].to;      }}void dfs2(int now,int high){    top[now]=high;    pos[now]=++tot;    num[tot]=s[now];    if(son[now]) dfs2(son[now],high);    for(int i=head[now];i;i=a[i].next)      if(a[i].to!=f[now]&&a[i].to!=son[now]) dfs2(a[i].to,a[i].to);}void addpath(int x,int y,int z){    int L,R;    if(top[x]==top[y])    {        L=min(pos[x],pos[y]);        R=max(pos[x],pos[y]);        return Add(L,R,1,n,1,z);    }    if(deep[top[x]]<deep[top[y]]) swap(x,y);    L=min(pos[x],pos[top[x]]);    R=max(pos[x],pos[top[x]]);    Add(L,R,1,n,1,z);    return addpath(y,f[top[x]],z);}inline int LCA(int x,int y){    while(top[x]!=top[y])      if(deep[top[x]]>deep[top[y]]) x=f[top[x]];      else y=f[top[y]];    return deep[x]<deep[y]?x:y;}inline int Ask(int x){    if(root==x) return t[1].num;    if(LCA(x,root)==x)    {        int ans=INF,from;        for(int i=head[x];i;i=a[i].next)          if(LCA(a[i].to,root)==a[i].to){from=a[i].to;break;}        if(pos[from]>1) ans=min(ans,ask(1,pos[from]-1,1,n,1));        if(pos[from]+size[from]<=n) ans=min(ans,ask(pos[from]+size[from],n,1,n,1));        return ans;    }    return ask(pos[x],pos[x]+size[x]-1,1,n,1);}

计算几何

//凸包const double eps=1e-10;struct point{    double x,y;    point(){}    point(double xx,double yy):x(xx),y(yy){}    inline point operator -(const point other)const    {        return point(x-other.x,y-other.y);    }    inline bool operator <(const point other)const    {        if(x==other.x) return y<other.y;        return x<other.x;    }}a[10005],s[10005];int n,top;double ans;inline int dcmp(double a,double b){    if(fabs(a-b)<eps) return 0;    return a>b?1:-1;}inline double cross(point a,point b){    return a.x*b.y-a.y*b.x;}inline void solve(){    sort(a+1,a+n+1);    for(int i=1;i<=n;i++)    {        while(top>1&&dcmp(cross(s[top]-s[top-1],a[i]-s[top-1]),0)<=0) top--;        s[++top]=a[i];    }    int num=top;    for(int i=n-1;i;i--)    {        while(top>num&&dcmp(cross(s[top]-s[top-1],a[i]-s[top-1]),0)<=0) top--;        s[++top]=a[i];    }}//半平面交#include<cmath>#include<cstdio>#include<algorithm>using namespace std;const double INF=1e100;const double eps=1e-10;const int N=305;struct point{    double x,y;    point(){}    point(double xx,double yy):x(xx),y(yy){}    inline point operator +(const point other)const    {        return point(x+other.x,y+other.y);    }    inline point operator -(const point other)const    {        return point(x-other.x,y-other.y);    }    inline point operator *(const double other)const    {        return point(x*other,y*other);    }};inline int dcmp(double a,double b){    if(fabs(a-b)<eps) return 0;    return a>b?1:-1;}inline double cross(point a,point b){    return a.x*b.y-b.x*a.y;}inline double supercross(point a,point b,point c){    return cross(point(b.x-a.x,b.y-a.y),point(c.x-b.x,c.y-b.y));}struct line{    point s,v;    line(){}    line(point ss,point vv):s(ss),v(vv){}    inline bool operator <(const line other)const    {        double rate1=atan2(v.y,v.x),rate2=atan2(other.v.y,other.v.x);        if(!dcmp(rate1,rate2)) return dcmp(supercross(s,s+v,other.s),0)==-1;        else return rate1<rate2;    }};inline point inter(line a,line b){    point u=b.s-a.s;    double rate=cross(u,b.v)/cross(a.v,b.v);    return a.s+(a.v*rate);}inline bool onleft(line a,point p){    return dcmp(supercross(a.s,a.s+a.v,p),0)>0;}inline double high(point a,point b,double p){    return inter(line(a,b-a),line(point(p,0),point(0,1))).y;}struct halfinter{    line a[N],q[N];    int n,h,t;    point tmp[N];    inline void solve()    {        sort(a+1,a+n+1);        q[h=t=1]=a[1];        for(int i=2;i<=n;i++)        {            if(!cross(a[i].v,a[i-1].v)) continue;            while(h<t&&!onleft(a[i],inter(q[t-1],q[t]))) t--;            while(h<t&&!onleft(a[i],inter(q[h],q[h+1]))) h++;            q[++t]=a[i];        }        while(h+1<t&&!onleft(q[h],inter(q[t],q[t-1]))) t--;        while(h+1<t&&!onleft(q[t],inter(q[h],q[h+1]))) h++;        for(int i=h;i<t;i++)          tmp[i]=inter(q[i],q[i+1]);    }}half;int x[N],y[N];int n;double ans=INF;int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)      scanf("%d",&x[i]);    for(int i=1;i<=n;i++)      scanf("%d",&y[i]);    for(int i=1;i<n;i++)      half.a[i]=line(point(x[i],y[i]),point(x[i+1]-x[i],y[i+1]-y[i]));    half.n=n+1;    half.a[n]=line(point(x[1],0),point(0,-1));    half.a[n+1]=line(point(x[n],0),point(0,1));    half.solve();    for(int i=half.h,j=1;i<=half.t;i++)    {        while(dcmp(x[j],half.tmp[i].x)>0||dcmp(half.tmp[i].x,x[j+1])>0) j++;        ans=min(ans,half.tmp[i].y-high(point(x[j],y[j]),point(x[j+1],y[j+1]),half.tmp[i].x));    }    for(int i=1,j=half.h;i<=n;i++)    {        while(dcmp(half.tmp[j].x,x[i])>0||dcmp(x[i],half.tmp[j+1].x)>0) j++;        ans=min(ans,high(half.tmp[j],half.tmp[j+1],x[i])-y[i]);    }    printf("%.3lf",ans);    return 0;}
0 0
原创粉丝点击