• 模板集合


    >w<

    Windows对拍:

     1 @echo off
     2 
     3 set paht=C:WindowsSystem32
     4 
     5 :loop
     6 
     7 data.exe
     8 ddd.exe
     9 pai.exe
    10 
    11 fc ddd.out pai.out
    12 
    13 if not errorlevel 1 goto loop
    14 
    15 pause
    16 
    17 goto loop
    View Code

    gvim配置:

    set ts=4
    set sw=4
    set smarttab
    set number
    color desert
    syntax on
    set cindent
    set guifont=Consolas:h16
    
    imap ee <Esc>:w<CR>
    View Code

     一行gcd:

    1 LL gcd(LL x,LL y){  return (y ? gcd(y,x%y) : x);}
    View Code

     线性基(带求交):

     1 struct bss{
     2     int b[32];
     3     bss(){
     4         for(int i=0;i<=31;++i)  b[i]=0;
     5     }
     6     bss(int x[]){
     7         for(int i=0;i<=31;++i)  b[i]=x[i];
     8     }
     9     void ist(int x){
    10         for(int i=31;i>=0;--i)if(x>>i&1){
    11             if(!b[i]){
    12                 b[i]=x;
    13                 return ;
    14             }
    15             x^=b[i];
    16         }
    17     }
    18     bool chck(int x){
    19         for(int i=31;i>=0;--i)if(x>>i&1)
    20             x^=b[i];
    21         return !x;
    22     }
    23 };
    24 bss mg(bss x,bss y){
    25     bss bwl=x,nb=x,z;
    26     for(int i=0;i<=31;++i)if(y.b[i]){
    27         int tma=0,tmb=y.b[i];
    28         for(int j=i;j>=0;--j)if(tmb>>j&1){
    29             if(bwl.b[j]){
    30                 tmb^=bwl.b[j],tma^=nb.b[j];
    31                 if(!tmb){
    32                     z.b[i]=tma;
    33                     break;
    34                 }
    35             }
    36             else{
    37                 bwl.b[j]=tmb;
    38                 nb.b[j]=tma;
    39                 break;
    40             }
    41         }
    42     }
    43     return z;
    44 }
    View Code

     (小根)堆:

     1 int hp[110000],sz=0;
     2 void ist(int z){
     3     int x;  hp[x=(++sz)]=z;
     4     while(x!=1 && hp[x]<hp[x>>1])  swap(hp[x],hp[x>>1]),x>>=1;
     5 }
     6 void pp(){
     7     hp[1]=hp[sz--];
     8     int x=1,mnid=1;
     9     for(;;){
    10         mnid=x;
    11         if((x<<1)<=sz && hp[x<<1]<hp[mnid])  mnid=(x<<1);
    12         if((x<<1|1)<=sz && hp[x<<1|1]<hp[mnid])  mnid=(x<<1|1);
    13         if(mnid==x)  break;
    14         swap(hp[mnid],hp[x]);
    15         x=mnid;
    16     }
    17 }
    View Code

     后缀数组(下标从1开始):

     1 char s[1100000];  int n=0;
     2 int rk[1100000],hght[1100000];
     3 int cnt[220],cntrk[1100000];
     4 int rk1[1100000],rk2[1100000];
     5 int sa[1100000],tmpsa[1100000];
     6 void gtsffxrk(){
     7     memset(cnt,0,sizeof(cnt));
     8     for(int i=1;i<=n;++i)  ++cnt[(int)s[i]];
     9     for(int i=1;i<=210;++i)  cnt[i]+=cnt[i-1];
    10     for(int i=1;i<=n;++i)  rk[i]=cnt[(int)s[i]];
    11     for(int l=1;l<n;l<<=1){
    12         for(int i=1;i<=n;++i)  rk1[i]=rk[i],rk2[i]=(i+l>n ? 0 : rk[i+l]);
    13         fill(cntrk+1,cntrk+1+n,0);
    14         //每一步都必须fill,因为cntrk求了前缀和,cntrk--并不会把所有cntrk都减成0
    15         for(int i=1;i<=n;++i)  ++cntrk[rk2[i]];
    16         for(int i=1;i<=n;++i)  cntrk[i]+=cntrk[i-1];
    17         //i从1开始,注意因为空字符的存在所以还是有0rank的
    18         for(int i=n;i>=1;--i)  tmpsa[cntrk[rk2[i]]--]=i;
    19         fill(cntrk+1,cntrk+1+n,0);
    20         for(int i=1;i<=n;++i)  ++cntrk[rk1[i]];
    21         for(int i=1;i<=n;++i)  cntrk[i]+=cntrk[i-1];
    22         for(int i=n;i>=1;--i)  sa[cntrk[rk1[tmpsa[i]]]--]=tmpsa[i];
    23         rk[sa[1]]=1;
    24         //如果rank从0开始,对于全部一样的串如"aaaa"会出问题,把最小的rank和空字符混淆
    25         bool flg=true;
    26         for(int i=2;i<=n;++i){
    27             rk[sa[i]]=rk[sa[i-1]];
    28             rk[sa[i]]+=(rk1[sa[i]]!=rk1[sa[i-1]] || rk2[sa[i]]!=rk2[sa[i-1]]);
    29             if(rk1[sa[i]]==rk1[sa[i]] || rk2[sa[i]]==rk2[sa[i]])  flg=false;
    30             //if(rk[sa[i]]==rk[sa[i-1]])  flg=false;
    31         }
    32         if(flg)  break;
    33     }
    34 }
    35 void gthght(){
    36     int l=0;
    37     for(int i=1;i<=n;++i)if(rk[i]>1){
    38         int j=sa[rk[i]-1];
    39         while(i+l<=n && j+l<=n && s[i+l]==s[j+l])  ++l;
    40         //i+l表示的实际上是长度为i+l-1的串的最后一个字符
    41         hght[rk[i]]=l;
    42         l-=(l>0);
    43     }
    44 }
    View Code

     dinic(当前弧优化):

     1 const LL oo=1000000000000007;
     2 struct edg{int y,nxt;  LL v;}e[11000];  int lk[110],ltp=1;
     3 //注意两倍边数组
     4 void ist(int x,int y,int z){
     5     e[++ltp]=(edg){y,lk[x],z};  lk[x]=ltp;
     6     //注意结构体内变量顺序
     7     e[++ltp]=(edg){x,lk[y],0};  lk[y]=ltp;
     8     //因为要用i^1表示反向边所以边的标号从2开始
     9 }
    10 int n,m;  int s,t;
    11 int lvl[110];
    12 int q[110],hd=0;
    13 int crt[110];
    14 bool gtlvl(){
    15     memset(lvl,0,sizeof(lvl));
    16     lvl[q[hd=1]=s]=1;
    17     for(int k=1;k<=hd;++k){
    18         crt[q[k]]=lk[q[k]];
    19         //注意crt要初始化
    20         for(int i=lk[q[k]];i;i=e[i].nxt)if(e[i].v && !lvl[e[i].y]){
    21             q[++hd]=e[i].y;
    22             lvl[e[i].y]=lvl[q[k]]+1;
    23         }
    24     }
    25     return lvl[t];
    26 }
    27 LL mxflw(int x,LL y){
    28     if(x==t)  return y;
    29     LL bwl=0,flw=0;
    30     for(int i=crt[x];i && bwl<y;i=e[i].nxt)if(lvl[e[i].y]==lvl[x]+1 && e[i].v)
    31     //注意i=crt[x]
    32         if((flw=mxflw(e[i].y,min(y-bwl,e[i].v)))){
    33         //注意y和v,易错点
    34             e[i].v-=flw,e[i^1].v+=flw;
    35             bwl+=flw;
    36             if(!e[i].v)  crt[x]=e[i].nxt;
    37             //唯一的改动,很好写
    38             //注意必须某条边跑满才能换下一个,否则会负优化
    39         }
    40     if(!bwl)  lvl[x]=0;
    41     return bwl;
    42 }
    43 LL dnc(){
    44     LL bwl=0,flw=0;
    45     while(gtlvl())while((flw=mxflw(s,oo)))  bwl+=flw;
    46     return bwl;
    47 }
    View Code

     平衡树treap(假删除):

     1 int c[110000][2],v[110000],u[110000],sz[110000],ntp=0,rt=0;
     2 int nb[110000],fth[110000];
     3 void rtt(int x,bool mk){
     4     int l=mk^1,r=mk,y=fth[x],z=fth[fth[x]];
     5     //l和r的选取必须看以左旋还是右旋为例
     6     if(c[x][r])  fth[c[x][r]]=y;
     7     //c[x][r]可能为空
     8     fth[y]=x,fth[x]=z;
     9     c[y][l]=c[x][r],c[x][r]=y;
    10     //x肯定有爸爸,没有爸爸旋个毛线
    11     if(z)  c[z][c[z][1]==y]=x;  //注意这里不是l和r
    12     //总共涉及到3条边,所以共有6个赋值
    13     sz[x]=sz[y],sz[y]=sz[c[y][0]]+sz[c[y][1]]+nb[y];
    14     if(y==rt)  rt=x;
    15     //注意rt
    16 }
    17 void mt(int x){
    18     while(fth[x] && u[x]<u[fth[x]])  rtt(x,c[fth[x]][0]==x);
    19 }
    20 void ist(int x,int y,int z){
    21     if(!x){
    22         x=++ntp;
    23         if(!rt)  rt=x;
    24         v[x]=z,u[x]=rand();
    25         sz[x]=1,nb[x]=1;
    26         fth[x]=y;  if(y)  c[y][z>v[y]]=x;
    27         //x肯定要设置爸爸,但爸爸可能为空,细节要考虑到
    28         c[x][0]=0,c[x][1]=0;
    29         mt(x);
    30         return ;
    31     }
    32     ++sz[x];
    33     if(z==v[x])  ++nb[x];
    34     else  ist(c[x][z>v[x]],x,z);
    35 }
    36 void dlt(int x,int z){
    37     if(!x)  return ;
    38     --sz[x];
    39     if(z==v[x])  --nb[x];
    40     else  dlt(c[x][z>v[x]],z);
    41     return ;
    42 }
    43 int gtrk(int x,int z){
    44     if(!x)  return -1;
    45     if(z==v[x])  return sz[c[x][0]]+1;
    46     else  return gtrk(c[x][z>v[x]],z)+(z>v[x] ? sz[c[x][0]]+nb[x] : 0);
    47 }
    48 int slct(int x,int z){
    49     if(!x)  return -1;
    50     if(z<=sz[c[x][0]])  return slct(c[x][0],z);
    51     //注意别写混成gtrk
    52     else if(z-sz[c[x][0]]<=nb[x])  return v[x];
    53     else  return slct(c[x][1],z-sz[c[x][0]]-nb[x]);
    54 }
    55 int gtcsctv(int x,int z,bool mk){
    56     int l=mk,r=mk^1;
    57     //前驱后继也是镜像操作
    58     while(v[x]!=z){
    59         if(!c[x][z>v[x]]){
    60             ist(rt,0,z),dlt(rt,z);
    61             //注意一定要从rt开始插入和删除,如果从x开始会有很多问题
    62             //比如被旋走,比如插入途径加的sz没有删干净
    63             x=ntp;
    64         }
    65         //保证第一遍查找的时候不会找到假节点
    66         else  x=c[x][z>v[x]];
    67         //注意一定要else,否则新插入的点可能会被maintain跑
    68     }
    69     if(!c[x][l]){
    70         while(fth[x] && c[fth[x]][r]!=x)  x=fth[x];
    71         if(!fth[x])  return -1;
    72         x=fth[x];
    73     }
    74     else{
    75         //注意这里是else,如果开始爸爸就不用再找儿子了
    76         x=c[x][l];
    77         while(c[x][r])  x=c[x][r];
    78     }
    79     if(nb[x])  return v[x];
    80     else  return gtcsctv(x,v[x],mk);
    81     //如果偷懒不删除则要注意找到的点是否已经没有数了
    82     //感觉这样容易反复查找被卡,但是没有证据
    83 }
    View Code

     cdq分治(三维数星星小于等于版):

     1 void cdq(int l,int r,int cl,int cr){
     2     if(l>=r)  return ;
     3     if(cl==cr){
     4         for(int i=l;i<=r;++i){
     5             int tmp=1;
     6             //注意这里对于全等点的处理
     7             while(i+tmp<=r && a[i+tmp].a==a[i].a && a[i+tmp].c==a[i].c)  ++tmp;
     8             //i+tmp表示的实际上是长度为tmp+1的区间的右端点
     9             for(int j=0;j<tmp;++j)  a[i+j].ans+=tmp-1+qry(a[i].c);
    10             //别忘了qry
    11             mdf(a[i].c,tmp);
    12             i+=tmp-1;
    13             //注意是+tmp-1不是=也不是+tmp
    14         }
    15         for(int i=l;i<=r;++i)  mdf(a[i].c,-1);
    16         return ;
    17     }
    18     int md=(cl+cr)>>1;
    19     int cnt1=0,cnt2=0;
    20     for(int i=l;i<=r;++i){
    21         if(a[i].b<=md){
    22             mdf(a[i].c,1);
    23             ++cnt1;
    24         }
    25         else{
    26             a[i].ans+=qry(a[i].c);
    27             ++cnt2;
    28         }
    29     }
    30     for(int i=l;i<=r;++i)if(a[i].b<=md)  mdf(a[i].c,-1);
    31     cnt1+=l;  cnt2+=cnt1;
    32     for(int i=r;i>=l;--i)  q[--(a[i].b<=md ? cnt1 : cnt2)]=a[i];
    33     for(int i=l;i<=r;++i)  a[i]=q[i];
    34     cdq(l,cnt2-1,cl,md),cdq(cnt2,r,md+1,cr);
    35 }
    36 bool cmp(nds x,nds y){  return (x.a==y.a ? (x.b==y.b ? x.c<y.c : x.b<y.b) : x.a<y.a);}
    37 //这个顺序很重要
    View Code

     树状数组:

    1 inline int lbt(int x){  return x&-x;}
    2 //v[x]统计的是[x-lowbit(x)+1,x]的所有数
    3 void mdf(int x,int z){  while(x<=m){  v[x]+=z;  x+=lbt(x);}}
    4 //+lowbit的目的不是把1变成0,而是把0变成1
    5 int qry(int x){
    6     int bwl=0;
    7     while(x){  bwl+=v[x];  x-=lbt(x);}
    8     return bwl;
    9 }
    View Code

     tarjan求割点(无向图):

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int rd(){int z=0,mk=1;  char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
     9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    10     return z*mk;
    11 }
    12 struct edg{int y,nxt;}e[210000];  int lk[21000],ltp=0;
    13 void ist(int x,int y){
    14     e[++ltp]=(edg){y,lk[x]};  lk[x]=ltp;
    15     e[++ltp]=(edg){x,lk[y]};  lk[y]=ltp;
    16 }
    17 int n,m;
    18 int dfn[21000],low[21000],dft=0;
    19 int aq[21000],atp=0;
    20 void tj(int x,int y){
    21     dfn[x]=++dft;  low[x]=dfn[x];
    22     bool flg1=false,flg2=false;
    23     for(int i=lk[x];i;i=e[i].nxt)if(e[i].y!=y){
    24         if(!dfn[e[i].y]){
    25             tj(e[i].y,x);
    26             if(!y && flg1)  flg2=true;
    27             //注意顺序!放到后边就错了
    28             if(low[e[i].y]>=dfn[x])  flg1=true;
    29             low[x]=min(low[x],low[e[i].y]);
    30         }
    31         else  low[x]=min(low[x],dfn[e[i].y]);
    32         //注意这里是dfn
    33     }
    34     if(y && flg1)  aq[++atp]=x;
    35     if(!y && flg2)  aq[++atp]=x;
    36 }
    37 void prvs(){
    38     for(int i=1;i<=n;++i)  dfn[i]=0,low[i]=0;
    39     dft=0;
    40     atp=0;
    41 }
    42 int main(){
    43     //freopen("ddd.in","r",stdin);
    44     cin>>n>>m;  prvs();
    45     int l,r;
    46     while(m --> 0){  l=rd(),r=rd();  ist(l,r);}
    47     for(int i=1;i<=n;++i)if(!dfn[i])  tj(i,0);
    48     sort(aq+1,aq+atp+1);
    49     printf("%d
    ",atp);
    50     for(int i=1;i<=atp;++i)  printf("%d ",aq[i]);
    51     printf("
    ");
    52     return 0;
    53 }
    View Code

    手写堆排序:

     1 nds a[110000];
     2 bool cmp(nds &x,nds &y){  return x.c<y.c;}
     3 void st(){
     4     for(int i=1;i<=m;++i)
     5         for(int j=i;j>1 && b[j].c<b[j>>1].c;j>>=1)  swap(b[j],b[j>>1]);
     6     int sz=m;
     7     for(int i=1;i<=m;++i){
     8         a[i]=b[1];
     9         swap(b[1],b[sz--]);
    10         for(int j=1;j<=sz;){
    11             int k=j;
    12             if((j<<1)<=sz && b[j<<1].c<b[k].c)  k=(j<<1);
    13             if((j<<1|1)<=sz && b[j<<1|1].c<b[k].c)  k=(j<<1|1);
    14             if(k==j)  break;
    15             swap(b[j],b[k]);
    16             j=k;
    17         }
    18     }
    19     for(int i=1;i<=m;++i)  b[i]=a[i];
    20 }
    View Code

    费用流:

     1 const int oo=1000000007;
     2 struct edg{int nxt,y,v,u;}e[31000];  int lk[4100],ltp=1;
     3 void ist(int x,int y,int z,int w){
     4     e[++ltp]=(edg){lk[x],y,z,w};  lk[x]=ltp;
     5     e[++ltp]=(edg){lk[y],x,0,-w};  lk[y]=ltp;
     6 }
     7 int n,m,ft,st,fc,sc,a[2100];
     8 int s,t;
     9 int dstc[4100];
    10 int q[41000],hd=0;  bool vstd[4100];
    11 int lst[4100],lse[4100];
    12 bool spfa(){
    13     for(int i=1;i<=t;++i){
    14         vstd[i]=false;
    15         dstc[i]=oo;
    16     }
    17     dstc[q[hd=1]=s]=0;
    18     for(int k=1;k<=hd;++k){
    19         for(int i=lk[q[k]];i;i=e[i].nxt)
    20             if(e[i].v && dstc[q[k]]+e[i].u<dstc[e[i].y]){
    21                 dstc[e[i].y]=dstc[q[k]]+e[i].u;
    22                 lst[e[i].y]=q[k],lse[e[i].y]=i;
    23                 if(!vstd[e[i].y]){
    24                     q[++hd]=e[i].y;
    25                     vstd[e[i].y]=true;
    26                 }
    27             }
    28         vstd[q[k]]=false;
    29     }
    30     //return dstc[t];  注意不是判断dstc[t]不为0
    31     return dstc[t]!=oo;
    32 }
    33 LL cstflw(){
    34     LL bwl=0;
    35     while(spfa()){
    36         int flw=oo;
    37         for(int i=t;i!=s;i=lst[i])
    38             flw=min(flw,e[lse[i]].v);
    39         for(int i=t;i!=s;i=lst[i]){
    40             bwl+=flw*e[lse[i]].u;
    41             e[lse[i]].v-=flw,e[lse[i]^1].v+=flw;
    42             //cout<<i<<"<-";
    43         }
    44         //cout<<endl;
    45     }
    46     return bwl;
    47 }
    View Code

     线筛求质数:

     1 int s[1100000];
     2 void gtprm(){
     3     for(int i=2;i<=m;++i){
     4         if(!flg[i])  prm[++prt]=i;
     5         for(int j=1;j<=prt && i*prm[j]<=m;++j){
     6             flg[i*prm[j]]=true;
     7             if(!(i%prm[j]))  break;
     8         }
     9     }
    10 }
    View Code

     splay(文艺平衡树,区间反转):

     1 struct nds{
     2     int f,c[2];
     3     int v,s;
     4     int d;
     5     nds(){
     6         f=0,c[0]=0,c[1]=0;
     7         v=0,s=0;
     8         d=0;
     9     }
    10 }t[110000];  int tt=0,rt=0;
    11 int n,m,a[110000];
    12 //pushup
    13 void psu(int x){
    14     t[x].s=t[t[x].c[0]].s+t[t[x].c[1]].s+1;
    15 }
    16 //pushdown
    17 void psd(int x){
    18     if(!t[x].d)  return ;
    19     int l=t[x].c[0],r=t[x].c[1];
    20     t[l].d^=1,t[r].d^=1;
    21     t[x].d=0;
    22     swap(t[x].c[0],t[x].c[1]);
    23 }
    24 //rotate
    25 void rtt(int x,int w){
    26     int y=t[x].f;
    27     int z=t[y].f;
    28     int r=(t[y].c[0]==x);
    29     int l=(r^1);
    30     if(z)  t[z].c[t[z].c[1]==y]=x;
    31     else  rt=x;
    32     t[t[x].c[r]].f=y,t[y].f=x,t[x].f=z;
    33     t[y].c[l]=t[x].c[r],t[x].c[r]=y;
    34     psu(y),psu(x);
    35 }
    36 //splay
    37 void spl(int x,int w){
    38     int y,z;
    39     while(t[x].f!=w){
    40         y=t[x].f;
    41         z=t[y].f;
    42         if(t[y].f!=w)  rtt(((t[y].c[0]==x)^(t[z].c[0]==y)) ? x : y,w);
    43         rtt(x,w);
    44     }
    45 }
    46 //select
    47 int slc(int x,int w){
    48     if(!x)  return 0;
    49     psd(x);  //注意pushdown
    50     if(w<=t[t[x].c[0]].s)  return slc(t[x].c[0],w);
    51     else if(w==t[t[x].c[0]].s+1)  return x;
    52     else  return slc(t[x].c[1],w-t[t[x].c[0]].s-1);
    53 }
    54 //estabilsh
    55 int est(int l,int r,int y){
    56     if(l>r)  return 0;
    57     int md=(l+r)>>1;
    58     int x=++tt;
    59     t[x].f=y,t[x].c[0]=0,t[x].c[1]=0;
    60     t[x].v=a[md],t[x].s=1;
    61     t[x].d=0;
    62     if(md-1>=l)  t[x].c[0]=est(l,md-1,x);
    63     if(r>=md+1)  t[x].c[1]=est(md+1,r,x);
    64     psu(x);
    65     return x;
    66 }
    67 void iod(int x){
    68     if(!x)  return ;
    69     psd(x);
    70     if(t[x].c[0])  iod(t[x].c[0]);
    71     printf("%d ",t[x].v);
    72     if(t[x].c[1])  iod(t[x].c[1]);
    73 }
    74 int main(){
    75     cin>>n>>m;
    76     for(int i=1;i<=n;++i)  a[i]=i;
    77     rt=est(1,n,0);
    78     int l,r;
    79     while(m --> 0){
    80         scanf("%d%d",&l,&r);
    81         if(l==r)  continue;  //注意特判
    82         //否则splay(y,x)出错
    83         int x=slc(rt,l),y=slc(rt,r);
    84         spl(x,0),spl(y,x);
    85         swap(t[x].v,t[y].v);  //画图即懂
    86         t[t[y].c[0]].d^=1;  //注意不是t[r]
    87     }
    88     iod(rt);
    89     return 0;
    90 }
    View Code

     堆优化的Dijkstra:

     1 const int oo=1000000007;
     2 struct edg{int nxt,y,v;}e[410000];  int lk[110000],ltp=0;
     3 void ist(int x,int y,int z){
     4     e[++ltp]=(edg){lk[x],y,z};  lk[x]=ltp;
     5     e[++ltp]=(edg){lk[y],x,z};  lk[y]=ltp;
     6 }
     7 struct nds{
     8     int x,y;
     9     bool operator<(nds z){  return y<z.y;}
    10 }hp[410000];  int sz=0;  //堆大小为边数
    11 void psh(nds z){
    12     hp[++sz]=z;
    13     for(int i=sz;i!=1 && hp[i]<hp[i>>1];i>>=1)  swap(hp[i],hp[i>>1]);
    14 }
    15 void pp(){
    16     hp[1]=hp[sz--];
    17     int x=1,mn=1;
    18     for(;;){
    19         mn=x;
    20         if((x<<1)<=sz && hp[x<<1]<hp[mn])  mn=(x<<1);
    21         if((x<<1|1)<=sz && hp[x<<1|1]<hp[mn])  mn=(x<<1|1);
    22         if(mn==x)  break;
    23         swap(hp[mn],hp[x]);
    24         x=mn;
    25     }
    26 }
    27 int n,m;
    28 int dstc[110000],lst[110000];
    29 void dij(int x){
    30     sz=0;
    31     for(int i=1;i<=n;++i)  dstc[i]=oo;
    32     dstc[x]=0;
    33     psh((nds){x,0});
    34     while(sz){
    35         while(sz && hp[1].y>dstc[hp[1].x])  pp();
    36         //最大队列长度为边数,因为每个边至多松弛一次
    37         //每松弛一次加一个点入队
    38         if(!sz)  break;
    39         x=hp[1].x;  dstc[x]=hp[1].y;  //x复用警告
    40         pp();
    41         for(int i=lk[x];i;i=e[i].nxt)if(dstc[x]+e[i].v<dstc[e[i].y]){
    42             dstc[e[i].y]=dstc[x]+e[i].v;
    43             psh((nds){e[i].y,dstc[e[i].y]});
    44             lst[e[i].y]=x;
    45         }
    46     }
    47 }
    View Code

     圆方树:

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 struct edg{int nxt,y;}e[810000];  int lk[210000],lhd=0;        //注意原图也要双倍
     5 void ist(int x,int y){
     6     e[++lhd]=(edg){lk[x],y};  lk[x]=lhd;
     7     e[++lhd]=(edg){lk[y],x};  lk[y]=lhd;
     8 }
     9 edg g[810000];  int gk[210000],ghd=0;
    10 void gst(int x,int y){
    11     g[++ghd]=(edg){gk[x],y};  gk[x]=ghd;
    12     g[++ghd]=(edg){gk[y],x};  gk[y]=ghd;
    13 }
    14 int n,m,o;
    15 int dfn[210000],low[210000],dfc=0;    //注意开双倍,因为有两种点
    16 int q[210000],hd;
    17 int cnt=0;
    18 int s[210000];
    19 int f[210000],ft=0;
    20 int ast[210000][20];
    21 int dp[210000];
    22 void tj(int x){
    23     dfn[x]=++dfc;
    24     low[x]=dfc;
    25     q[++hd]=x;
    26     for(int i=lk[x];i;i=e[i].nxt){
    27         if(!dfn[e[i].y]){
    28             tj(e[i].y);
    29             low[x]=min(low[x],low[e[i].y]);
    30             if(low[e[i].y]==dfn[x]){              //找到一个点双
    31                 ++cnt;                            //增加方点个数
    32                 for(int j=0;j!=e[i].y;--hd){    //将点双中除了u的点退栈,并在圆方树中连边
    33                     j=q[hd];
    34                     gst(cnt,j);
    35                 }
    36                 gst(cnt,x);                        //u自身也要连边,但不退栈
    37             }
    38         }
    39         else{
    40             low[x]=min(low[x],dfn[e[i].y]);
    41         }
    42     }
    43 }
    44 void gte(){        //从临时图g转移到常用图e
    45     for(int i=1;i<=cnt;++i)  lk[i]=gk[i];
    46     for(int i=1;i<=ghd;++i)  e[i]=g[i];
    47     lhd=ghd;
    48 }
    49 void dfs(int x,int y){
    50     f[x]=ft;
    51     s[x]=s[y];
    52     if(x<=n)  s[x]++;
    53     dp[x]=dp[y]+1;
    54     ast[x][0]=y;
    55     for(int i=1;(1<<i)<=dp[x];++i)  ast[x][i]=ast[ast[x][i-1]][i-1];
    56     for(int i=lk[x];i;i=e[i].nxt)if(e[i].y!=y){
    57         dfs(e[i].y,x);
    58     }
    59 }
    60 int lca(int x,int y){
    61     if(dp[x]<dp[y])  swap(x,y);
    62     int tmp=dp[x]-dp[y];
    63     for(int i=0;i<=19;++i)if((1<<i)&tmp)  x=ast[x][i];
    64     for(int i=16;i>=0;--i)if(ast[x][i]!=ast[y][i]){
    65         x=ast[x][i];
    66         y=ast[y][i];
    67     }
    68     if(x==y)  return x;
    69     else  return ast[x][0];
    70 }
    71 int main(){
    72     scanf("%d%d",&n,&m);
    73     cnt=n;
    74     int l,r;
    75     for(int i=1;i<=m;++i){
    76         scanf("%d%d",&l,&r);
    77         ist(l,r);
    78     }
    79     for(int i=1;i<=n;++i)if(!dfn[i]){
    80         tj(i);
    81         --hd;    //dfs完了还有一个根,要退栈
    82     }
    83     gte();
    84     for(int i=1;i<=n;++i)if(f[i]==0){
    85         ft++;
    86         dfs(i,0);
    87     }
    88     scanf("%d",&o);
    89     while(o --> 0){
    90         scanf("%d%d",&l,&r);
    91         int u=lca(l,r);
    92         printf("%d
    ",s[l]+s[r]-s[u]-s[ast[u][0]]);
    93     }
    94     return 0;
    95 }
    View Code

     平面最近点对:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 using namespace std;
     6 const double oo=1e16;
     7 struct nds{double x,y;}a[210000];
     8 int n;
     9 nds b[210000];
    10 nds q[210000];  int hd=0,tl=1;
    11 inline double sqr(double x){  return x*x;}
    12 inline double dst(nds x,nds y){
    13     return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y));
    14 }
    15 double dvs(int l,int r){
    16     if(l==r)  return oo;
    17     if(l+1==r){
    18         if(a[l].y>a[r].y)  swap(a[l],a[r]);  //记得两个点也要排序
    19         return dst(a[l],a[r]);
    20     }
    21     int md=(l+r)>>1;
    22     double mdx=a[md].x;  //注意记录中点坐标,否则排完序就错了
    23     double d=min(dvs(l,md),dvs(md+1,r));
    24     int hd1=l,hd2=md+1;
    25     for(int i=l;i<=r;++i){
    26         if(hd1>md)  b[i]=a[hd2++];
    27         else if(hd2>r)  b[i]=a[hd1++];
    28         else if(a[hd1].y<a[hd2].y)  b[i]=a[hd1++];
    29         else  b[i]=a[hd2++];
    30     }
    31     for(int i=l;i<=r;++i)  a[i]=b[i];
    32     double mn=d;  //注意初值是d而不是oo
    33     hd=0,tl=1;
    34     for(int i=l;i<=r;++i)if(fabs(a[i].x-mdx)<d){
    35         q[++hd]=a[i];
    36         while(fabs(q[tl].y-q[hd].y)>d)  tl++;
    37         for(int j=tl;j<hd;++j)  mn=min(mn,dst(q[j],a[i]));
    38     }
    39     return mn;
    40 }
    41 bool cmp(nds x,nds y){
    42     return x.x<y.x;
    43 }
    44 int main(){
    45     scanf("%d",&n);
    46     for(int i=1;i<=n;++i){
    47         scanf("%lf%lf",&a[i].x,&a[i].y);
    48     }
    49     sort(a+1,a+n+1,cmp);
    50     printf("%.4lf
    ",dvs(1,n));
    51     return 0;
    52 }
    View Code

     KMBFS(严格n^3):

     1 ll s[410];
     2 ll e[410][410];
     3 //e[i][j]是左边第i个和右边第j个匹配的贡献
     4 int prv[410],nxt[410];
     5 //算法跑完后nxt就是左边匹配的右边
     6 //如果nxt[i]为0就表示没匹配
     7 ll slc[410];
     8 ll dbx[410],dby[410];
     9 bool vst[410];
    10 void bfs(int x){
    11     int px=0,py=0,yy=0;
    12     ll d=oo;
    13     for(int i=1;i<=n;++i){
    14         prv[i]=0;
    15         slc[i]=oo;
    16     }
    17     nxt[py]=x;
    18     do{
    19         px=nxt[py];
    20         d=oo;
    21         vst[py]=1;
    22         for(int i=1;i<=n;++i)if(vst[i]==0){
    23             if(slc[i]>dbx[px]+dby[i]-e[px][i]){
    24                 slc[i]=dbx[px]+dby[i]-e[px][i];
    25                 prv[i]=py;
    26             }
    27             if(slc[i]<d){
    28                 d=slc[i];
    29                 yy=i;
    30             }
    31         }
    32         for(int i=0;i<=n;++i){
    33             if(vst[i]){
    34                 dbx[nxt[i]]-=d;
    35                 dby[i]+=d;
    36             }
    37             else  slc[i]-=d;
    38         }
    39         py=yy;
    40     }while(nxt[py]!=0);
    41     while(py){
    42         nxt[py]=nxt[prv[py]];
    43         py=prv[py];
    44     }
    45 }
    46 void km(){
    47     for(int i=1;i<=n;++i){
    48         dbx[i]=0;
    49         dby[i]=0;
    50         nxt[i]=0;
    51     }
    52     for(int i=1;i<=n;++i){
    53         for(int j=1;j<=n;++j)  vst[j]=0;
    54         bfs(i);
    55     }
    56 }
    57 int main(){
    58     e[i][j]=s[bsc(b[i]+c[j])];
    59     km();
    60     ll bwl=0;
    61     for(int i=1;i<=n;++i)if(nxt[i]!=0)
    62         bwl+=e[nxt[i]][i];
    63     printf("%lld
    ",bwl);
    64 
    65 }
    View Code

     二次剩余(Python):

     1 from random import randint
     2 
     3 
     4 def mul_i(a, b, t, p):
     5     return [(a[0] * b[0] + a[1] * b[1] * t) % p, (a[0] * b[1] + b[0] * a[1]) % p]
     6 
     7 
     8 def pow_i(a, b, c, t, p):
     9     ans = [1, 0]
    10     z = [a, b]
    11     while c > 0:
    12         if c % 2 == 1:
    13             ans = mul_i(ans, z, t, p)
    14         z = mul_i(z, z, t, p)
    15         c = c // 2
    16 
    17     return ans
    18 
    19 
    20 def legendre(a, p):
    21     return pow(a, (p - 1) // 2, p)
    22 
    23 
    24 def residue(n, p):
    25     t = randint(0, p - 1)
    26     while legendre(t ** 2 - n, p) != p - 1:
    27         t = randint(0, p - 1)
    28 
    29     a = pow_i(t, 1, (p + 1) // 2, t ** 2 - n, p)
    30     return a[0]
    31 
    32 
    33 if __name__ == '__main__':
    34     T = int(input())
    35     for t in range(T):
    36         n, p = [int(i) for i in input().split(' ')]
    37         if legendre(n, p) == p - 1:
    38             print('No solution!')
    39         elif legendre(n, p) == 0:
    40             print(0)
    41         else:
    42             a = residue(n, p)
    43             b = p - a
    44             if a > b:
    45                 a, b = b, a
    46             if a == b:
    47                 print(a)
    48             else:
    49                 print(a, b)
    View Code

    >w<

  • 相关阅读:
    CoreText实现图文混排之点击事件
    iOS仿喜马拉雅FM做的毕业设计及总结(含新手福利源码)
    iOS---多线程实现方案一 (pthread、NSThread)
    iOS中navigationItem的titleView如何居中
    从 setNeedsLayout 说起
    精准化测试专业平台Paw:苹果APP应用代码质量的守护者
    Runtime实战之定制TabBarItem大小
    YYModel 源码历险记 代码结构
    10分钟搞定支付宝和微信支付 的 各种填坑
    如何写好一个UITableView
  • 原文地址:https://www.cnblogs.com/cdcq/p/11211945.html
Copyright © 2020-2023  润新知