模板库(持续更新……)

蒟蒻的模板库

 

突然发现模板什么的需要存一下了= =因为蒟蒻并没有全部记住……

一些算法/数据结构的模板就放自己其他博文的链接了,另一些会在这里直接写下来。

以前的我会慢慢整理……今天先写一个→_→(明显还是在偷懒啊喂!能不能靠谱一点啊?)

 

数学相关:

 1 void add(int k,int v){
 2 //    printf("add %d %d\n",k,v);
 3     F(j,1,tot){
 4         int x=k;
 5         while(x){
 6             b[j]+=x/prime[j]*v;
 7             x/=prime[j];
 8         }
 9     }
10 }
View Code(阶乘分解质因数)

 递推求逆元:

令$a=\lfloor \frac{p}{i}\rfloor$,$b=p\ mod\ i$

则有 $a*i=-b \pmod p$

所以$i^{-1}=-a*b^{-1}$

1 inv[0]=inv[1]=1;
2 F(i,2,n) inv[i]=p-(p/i)*inv[p%i]%p;
View Code

 原根&将数分拆为 $p_i^{a_i}$ :【BZOJ】【2219】数论之神

 1 void Split(int x){
 2     num=0;
 3     for(int i=2;i*i<=x;i++)
 4         if (x%i==0){
 5             a[++num].p=i;
 6             a[num].c=0; a[num].pc=1;
 7             while(x%i==0)
 8                 x/=i,a[num].c++,a[num].pc*=i;
 9             if (x==1) break;
10         }
11     if (x!=1)
12         a[++num].p=x,a[num].pc=x,a[num].c=1;
13 }
split
 1 LL Get_yuangen(LL p,LL phi){
 2     int c=0;
 3     for(int i=2;i*i<=phi;i++)
 4         if (phi%i==0)
 5             f[++c]=i,f[++c]=phi/i;
 6     for(int g=2;;g++){
 7         int j;
 8         for(j=1;j<=c;j++) if (Pow(g,f[j],p)==1) break;
 9         if (j==c+1) return g;
10     }
11     return 0;
12 }
原根

 

高精度:

  【BZOJ】【1089】【SCOI2003】严格n元树 代码节选:

 1 struct bint{
 2     int l,v[1010];
 3     bint(){l=0;memset(v,0,sizeof v);}
 4     int& operator [] (int x){return v[x];}
 5 }f[20];
 6 const int Limit=10000;
 7 void print(bint a){
 8     printf("%d",a[a.l]);
 9     D(i,a.l-1,1) printf("%04d",a[i]);
10     puts("");
11 }
12 bint operator * (bint a,bint b){
13     bint c;
14     F(i,1,a.l+b.l) c[i]=0;
15     F(i,1,a.l) F(j,1,b.l)
16         c[i+j-1]+=a[i]*b[j];
17     c.l=a.l+b.l;
18     F(i,1,c.l)
19         if (c[i]>=Limit){
20             if (i==c.l){
21                 c.l++;
22                 c[i+1]=c[i]/Limit;
23             }else c[i+1]+=c[i]/Limit;
24             c[i]%=Limit;
25         }
26     while(c.l>1 && !c[c.l]) c.l--;
27     return c;
28 }
29 bint operator + (bint a,int p){
30     a[1]+=p;
31     int now=1;
32     while(a[now]>=Limit){
33         a[now+1]+=a[now]/Limit;
34         a[now]%=Limit;
35         now++;
36         a.l=max(a.l,now);
37     }
38     return a;
39 }
40 bint operator - (bint a,bint b){
41     F(i,1,a.l){
42         a[i]-=b[i];
43         if (a[i]<0){
44             a[i]+=Limit;
45             a[i+1]--;
46         }
47     }
48     while(a.l>1 && !a[a.l]) a.l--;
49     return a;
50 }
51 bint operator ^ (bint a,int b){
52     bint r; r[r.l=1]=1;
53     for(;b;b>>=1,a=a*a)
54         if (b&1) r=r*a;
55     return r;
56 }
View Code

   【ContestHunter】【弱省胡策】【Round7】高精除单精:

1 void del(bint& a,const int &b){
2     LL tmp=0,last=0;
3     D(i,a.l,1){
4         tmp=(a[i]+last*Limit)%b;
5         a[i]=(a[i]+last*Limit)/b;
6         last=tmp;
7     }
8     while(a[a.l]==0 && a.l) a.l--;
9 }
View Code

 

KD-Tree:

1.【BZOJ】【2850】【Violet 0】巧克力王国

建树:

 1 void Push_up(int o){
 2     F(i,0,1){
 3         t[o].mn[i]=min(t[o][i],min(t[L].mn[i],t[R].mn[i]));
 4         t[o].mx[i]=max(t[o][i],max(t[L].mx[i],t[R].mx[i]));
 5     }
 6     t[o].sum=t[L].sum+t[R].sum+t[o].v;
 7 }
 8 
 9 inline int build(int l,int r,int dir){
10     D=dir;
11     nth_element(t+l,t+mid,t+r+1);
12     int o=mid;
13     L=l<mid ? build(l,mid-1,dir^1) : 0;
14     R=mid<r ? build(mid+1,r,dir^1) : 0;
15     Push_up(o);
16     return o;
17 }
View Code

2.【BZOJ】【2626】JZPFAR

找第K远点:

 1 inline LL dis(Poi a,Poi b){return (LL)sqr(a[0]-b[0])+(LL)sqr(a[1]-b[1]);}
 2 inline LL getdis(int o){
 3     if (!o) return -2;
 4     LL ans=0;
 5     F(i,0,1)
 6         ans+=max((LL)sqr(t[o].mx[i]-now[i]),(LL)sqr(t[o].mn[i]-now[i]));
 7     return ans;
 8 }
 9 priority_queue<node>Q;
10  
11 void query(int o){
12     if (!o) return;
13     LL dl=getdis(L),dr=getdis(R),d0=dis(t[o],now);
14     if (d0>Q.top().dis || (d0==Q.top().dis && t[o].num<Q.top().num)){
15         Q.pop(); Q.push(node(d0,t[o].num));
16     }
17     if (dl>dr){
18         if (dl>=Q.top().dis) query(L);
19         if (dr>=Q.top().dis) query(R);
20     }else{
21         if (dr>=Q.top().dis) query(R);
22         if (dl>=Q.top().dis) query(L);
23     }
24 }
View Code

3.【BZOJ】【1941】【SDOI2010】Hide and Seek

找最近/远点:

 1 int dis(int a){return abs(t[a][0]-t[tmp][0])+abs(t[a][1]-t[tmp][1]);}
 2 int calc_mn(int o){
 3     if (!o) return INF;
 4     int ans=0;
 5     F(i,0,1) ans+=max(0,t[o].mn[i]-t[tmp][i]);
 6     F(i,0,1) ans+=max(0,t[tmp][i]-t[o].mx[i]);
 7     return ans;
 8 }
 9  
10 void query_mn(int o){
11     if (!o) return;
12     int dl=calc_mn(L),dr=calc_mn(R),d0=dis(o);
13     if (d0) ask_mn=min(ask_mn,d0);
14     if (dl<dr){
15         if (dl<ask_mn) query_mn(L);
16         if (dr<ask_mn) query_mn(R);
17     }else{
18         if (dr<ask_mn) query_mn(R);
19         if (dl<ask_mn) query_mn(L);
20     }
21 }
22  
23 int calc_mx(int o){
24     if (!o) return -INF;
25     int ans=0;
26     F(i,0,1) ans+=max(abs(t[o].mn[i]-t[tmp][i]),abs(t[o].mx[i]-t[tmp][i]));
27     return ans;
28 }
29 void query_mx(int o){
30     if (!o) return;
31     int dl=calc_mx(L),dr=calc_mx(R),d0=dis(o);
32     ask_mx=max(ask_mx,d0);
33     if (dl>dr){
34         if (dl>ask_mx) query_mx(L);
35         if (dr>ask_mx) query_mx(R);
36     }else{
37         if (dr>ask_mx) query_mx(R);
38         if (dl>ask_mx) query_mx(L);
39     }
40 }
41  
View Code

4.【BZOJ】【4066】简单题(强制在线)

Insert:

 1 inline void Insert(int &o,int dir){
 2     if (!o){
 3         o=++tot; t[o]=now;
 4         F(i,0,1) t[o].mn[i]=t[o].mx[i]=t[o][i];
 5         t[o].D=dir;
 6         t[o].size=1;
 7         t[o].sum=t[o].v;
 8         return;
 9     }
10     if (now[dir]<t[o][dir]){
11         Insert(L,dir^1);
12         Push_up(o);
13         if ((double)t[L].size>(double)t[o].size*0.7) rebuild(o);
14     }
15     else{
16         Insert(R,dir^1);
17         Push_up(o);
18         if ((double)t[R].size>(double)t[o].size*0.7) rebuild(o);
19     }
20 }
View Code

 rebuild的姿势:

 1 inline int build(int l,int r,int dir){
 2     D=dir;
 3     nth_element(p+l,p+mid,p+r+1,cmp);
 4     int o=p[mid];
 5     t[o].D=dir;
 6     F(i,0,1) t[o].mn[i]=t[o].mx[i]=t[o][i];
 7     t[o].sum=t[o].v;
 8     L=l<mid ? build(l,mid-1,dir^1) : 0;
 9     R=mid<r ? build(mid+1,r,dir^1) : 0;
10     Push_up(o);
11     return o;
12 }
13 inline void dfs(int o){
14     if (!o) return;
15     dfs(L);
16     p[++cnt]=o;
17     dfs(R);
18 }
19 inline void rebuild(int &o){
20     cnt=0;
21     dfs(o);
22     o=build(1,cnt,t[o].D);
23 }
View Code

区域求和:

 1 int query(int o,int x1,int y1,int x2,int y2){
 2     if (!o) return 0;
 3     if (t[o].mn[0]>=x1 && t[o].mn[1]>=y1 && t[o].mx[0]<=x2 && t[o].mx[1]<=y2)
 4         return t[o].sum;
 5     else{
 6         int ans=0;
 7         if (t[o][0]>=x1 && t[o][0]<=x2 && t[o][1]>=y1 && t[o][1]<=y2) ans+=t[o].v;
 8         if (t[L].mn[0]>x2 || t[L].mx[0]<x1 || t[L].mn[1]>y2 || t[L].mx[1]<y1) ;
 9         else ans+=query(L,x1,y1,x2,y2);
10         if (t[R].mn[0]>x2 || t[R].mx[0]<x1 || t[R].mn[1]>y2 || t[R].mx[1]<y1) ;
11         else ans+=query(R,x1,y1,x2,y2);
12         return ans;
13     }
14 }
View Code

 

可持久化Trie:

【BZOJ】【2741】【FOTILE模拟赛】L

(这个板子只是搞异或,不过需要用可持久化Trie的时候……基本都是在搞Xor?)

 1 int n,m,q,tot,rt[N],id[M],t[M][2],a[N],b[150][N];
 2 
 3 inline void Ins(int pre,int x,int k){
 4     int now=rt[k]=++tot; id[tot]=k;
 5     D(i,30,0){
 6         int j=(x>>i)&1;
 7         t[now][j^1]=t[pre][j^1];
 8         t[now][j]=++tot; id[tot]=k;
 9         now=tot;
10         pre=t[pre][j];
11     }
12 }
13 inline int ask(int l,int r,int x){
14     int ans=0,now=rt[r];
15     D(i,30,0){
16         int j=((x>>i)&1)^1;
17         if (id[t[now][j]]>=l) ans|=1<<i; else j^=1;
18         now=t[now][j];
19     }
20     return ans;
21 }
View Code

 判n个区间的交是否为空:

【XJOI】【NOI考前模拟赛7】

  进入区间+1,离开区间-1,每个区间的左右端点都视为一个事件,排序一下,看是否某一时刻前缀和为n即可。

点分治:

【BZOJ】【3697】采药人的路径 & 【3127】【USACO2013 Open】Yin and Yang

 1 int n,rt,s[N],h[N],size,dep[N];
 2 bool vis[N];
 3 //LL ans,g[N*2][2],f[N*2][2];
 4 //int t[N<<1],dis[N],mxdeep;
 5 
 6 /*
 7  *     size=n; h[rt=0]=n+1;
 8     getroot(1,0);
 9     getans(rt);
10     printf("%lld\n",ans)
11 */
12 
13 inline void getroot(int x,int fa){
14     s[x]=1; h[x]=0;
15     for(int i=head[x];i;i=nxt[i])
16         if (to[i]!=fa && !vis[to[i]]){
17             getroot(to[i],x);
18             s[x]+=s[to[i]];
19             h[x]=max(h[x],s[to[i]]);
20         }
21     h[x]=max(h[x],size-s[x]);
22     if (h[x]<h[rt]) rt=x;
23 }
24 
25 inline void dfs(int x,int fa){
26     mxdeep=max(mxdeep,dep[x]);
27     if (t[dis[x]]) g[dis[x]][1]++;
28     else g[dis[x]][0]++;
29     t[dis[x]]++;
30     for(int i=head[x];i;i=nxt[i])
31         if (!vis[to[i]] && to[i]!=fa){
32             dep[to[i]]=dep[x]+1;
33             dis[to[i]]=dis[x]+v[i];
34             dfs(to[i],x);
35         }
36     t[dis[x]]--;
37 }//用来得到所需的子树的信息
38     
39 inline void getans(int x){
40     int mx=0;
41     vis[x]=1; f[n][0]=1;
42     for(int i=head[x];i;i=nxt[i])
43         if (!vis[to[i]]){
44             //xxxxx
45             dfs(to[i],x);
46             //xxxxx
47         }
48     F(i,n-mx,n+mx) f[i][0]=f[i][1]=0;
49     //清空统计数组
50 
51     //统计答案↑
52     for(int i=head[x];i;i=nxt[i])
53         if (!vis[to[i]]){
54             rt=0; size=s[to[i]];
55             getroot(to[i],x);
56             getans(rt);
57         }
58     //继续分治↑
59 }
View Code

 平衡树维护凸包:

  http://blog.csdn.net/auto_ac/article/details/10664641

  【ContestHunter】【弱省胡策】【Round8】(加了维护斜率/凸包上二分)

 1 typedef map<double,double> mii;
 2 typedef map<double,double>::iterator iter;
 3 #define X first
 4 #define Y second
 5 double cross(iter o,iter a,iter b){
 6     return (a->X - o->X) * (b->Y - o->Y) -
 7            (a->Y - o->Y) * (b->X - o->X);
 8 }
 9 mii up,slop;
10 
11 inline double slope(iter a,iter b){
12     return (b->Y - a->Y)/(b->X - a->X);
13 }
14 bool inside(mii &p,double x,double y){
15     if (!p.size()) return 0;
16     if (x<p.begin()->X || x>p.rbegin()->X) return 0;
17     if (p.count(x)) return y<=p[x];
18     p[x]=y;
19     iter cur = p.lower_bound(x),i,j;
20     i=j=cur; i--; j++;
21     bool ret=cross(i,cur,j)>=0;
22     p.erase(cur);
23     return ret;
24 }
25 void add(mii &p,double x,double y){
26     if (inside(p,x,y)) return;
27     if (p.count(x)){
28         iter cur=p.lower_bound(x),i=cur,j=cur;
29         i--;j++;
30         if (cur!=p.begin()) slop.erase(slope(i,cur));
31         if (j!=p.end()) slop.erase(slope(cur,j));
32     }
33     p[x]=y;
34     iter cur=p.lower_bound(x),i=cur,j=cur;
35     i--; j++;
36     if (cur!=p.begin() && j!=p.end()) slop.erase(slope(i,j));
37     if (cur!=p.begin()) slop[slope(i,cur)]=cur->X;
38     if (j!=p.end()) slop[slope(cur,j)]=j->X;
39     for(i=cur,i--,j=i,j--;i!=p.begin() && cur!=p.begin();i=j--)
40         if (cross(j,i,cur)>=0){
41             slop.erase(slope(j,i));
42             slop.erase(slope(i,cur));
43             slop[slope(j,cur)]=cur->X;
44             p.erase(i);
45         }
46         else break;
47     for(i=cur,i++,j=i,j++;i!=p.end() && j!=p.end();i=j++)
48         if (cross(cur,i,j)>=0){
49             slop.erase(slope(cur,i));
50             slop.erase(slope(i,j));
51             slop[slope(cur,j)]=j->X;
52             p.erase(i);
53         }
54         else break;
55 }
56 double query(double k){
57     double x,y;
58     iter it=slop.lower_bound(k);
59     if (it==slop.end()) x=up.begin()->X,y=up.begin()->Y;
60     else x=it->Y,y=up[x];
61 //    printf("query k=%f tmpk=%f x=%f y=%f\n",k,it->X,x,y);
62     return y-k*x;
63 }
View Code

 

posted @ 2015-05-15 17:49  Tunix  阅读(...)  评论(...编辑  收藏