模板

1.FFT

 1 void fft(int n,Complex *x,int cvs)
 2 {
 3     for (int i=0,j=0;i<n;i++)
 4     {
 5         if (i<j) swap(x[i],x[j]);
 6         for (int l=(n>>1);(j^=l)<l;l>>=1);
 7     }
 8     for (int i=2;i<=n;i<<=1)
 9     {
10         int l=(i>>1);
11         for (int j=0;j!=n;j+=i)
12         {
13             Complex wn,w;
14             wn=Complex(1,0);
15             w=Complex(cos(2*pi/i*cvs),sin(2*pi/i*cvs));
16             for (int k=0;k<l;k++)
17             {
18                 Complex t=wn*x[j+l+k];
19                 x[j+l+k]=x[j+k]-t;
20                 x[j+k]=x[j+k]+t;
21                 wn=wn*w;
22             }
23         }
24     }
25 }
FFT

2.Splay

  1 #include <bits/stdc++.h>
  2 #define inf (int)1e9
  3 using namespace std;
  4 const int N=1e5+100;
  5 int n,tot,root,val[N],sz[N],son[N][2];
  6 int fa[N],sf[N],re[N];
  7 int newnode()
  8 {
  9     return tot++;
 10 }
 11 void connect(int x,int y,int dir)
 12 {
 13     son[y][dir]=x;
 14     fa[x]=y;
 15     sf[x]=dir;
 16 }
 17 void pushup(int x)
 18 {
 19     sz[x]=sz[son[x][0]]+sz[son[x][1]]+re[x];
 20 }
 21 void clear()
 22 {
 23     val[0]=son[0][0]=son[0][1]=sz[0]=re[0]=fa[0]=sf[0]=0;
 24 }
 25 void rotate(int x)
 26 {
 27     int f,gf,xd,fd,s;
 28     f=fa[x];gf=fa[f];
 29     xd=sf[x];fd=sf[f];
 30     s=son[x][xd^1];
 31     connect(x,gf,fd);connect(f,x,xd^1);connect(s,f,xd);
 32     clear();
 33     pushup(f);pushup(x);
 34 }
 35 void splay(int x,int y)
 36 {
 37     while (fa[x]!=y)
 38     {
 39         if (fa[fa[x]]==y)
 40           rotate(x);
 41         else
 42         if (sf[fa[x]]==sf[x])
 43         {
 44             rotate(fa[x]);
 45             rotate(x);
 46         }
 47         else
 48         {
 49             rotate(x);
 50             rotate(x);
 51         }
 52     }
 53     if (y==0)
 54       root=x;
 55 }
 56 void find(int v)
 57 {
 58     int cur=root;
 59     while (son[cur][v>val[cur]] && val[cur]!=v)
 60       cur=son[cur][v>val[cur]];
 61     splay(cur,0);
 62 }
 63 int per(int v)
 64 {
 65     find(v);
 66     if (val[root]<v) return root;
 67     int cur=son[root][0];
 68     while (son[cur][1]) cur=son[cur][1];
 69     return cur;
 70 }
 71 int suc(int v)
 72 {
 73     find(v);
 74     if (val[root]>v) return root;
 75     int cur=son[root][1];
 76     while (son[cur][0]) cur=son[cur][0];
 77     return cur;
 78 }
 79 void insert(int v)
 80 {
 81     
 82     if (root==0)
 83     {
 84         int x=newnode();
 85         val[x]=v;sz[x]=1;
 86         root=x;
 87         return;
 88     }
 89     int cur=root;
 90     while (son[cur][v>val[cur]] && val[cur]!=v)
 91       cur=son[cur][v>val[cur]];
 92     if (val[cur]==v)
 93     {
 94         re[cur]++;sz[cur]++;
 95         splay(cur,0);
 96         return;
 97     }
 98     int x=newnode();
 99     val[x]=v;re[x]=sz[x]=1;
100     connect(x,cur,v>val[cur]);
101     pushup(cur);
102     splay(x,0);
103 }
104 void del(int v)
105 {
106     int p,s;
107     p=per(v);s=suc(v);
108     splay(p,0);
109     splay(s,p);
110     re[son[s][0]]--;sz[son[s][0]]--;
111     if (re[son[s][0]]==0)
112       son[s][0]=0;
113     pushup(s);pushup(p);
114 }
115 int rk(int v)
116 {
117     find(v);
118     return sz[son[root][0]];
119 }
120 int kth(int x,int k)
121 {
122     if (k>sz[son[x][0]]+re[x])
123       return kth(son[x][1],k-sz[son[x][0]]-re[x]);
124     if (k<=sz[son[x][0]])
125       return kth(son[x][0],k);
126     return x;
127 }
128 int main()
129 {
130     tot=1;
131     insert(inf);insert(-inf);
132     scanf("%d",&n);
133     for (int i=1;i<=n;i++)
134     {
135         int op,x;
136         scanf("%d%d",&op,&x);
137         if (op==1) insert(x);
138         if (op==2) del(x);
139         if (op==3) printf("%d\n",rk(x));
140         if (op==4) printf("%d\n",val[kth(root,x+1)]);
141         if (op==5) printf("%d\n",val[per(x)]);
142         if (op==6) printf("%d\n",val[suc(x)]);
143     }
144 }
普通平衡树
  1 #include <bits/stdc++.h>
  2 #define inf (int)1e9
  3 using namespace std;
  4 const int N=500100;
  5 int n,m,tot,root,a[N];
  6 struct node
  7 {
  8     int sz,val,sum,res,lx,rx,tx,vc;
  9     int son[2],fa,sf;
 10 }sh[N+100];
 11 queue <int> q;
 12 int newnode()
 13 {
 14     int x;
 15     if (tot>=N)
 16     {
 17         x=q.front();
 18         q.pop();
 19     }
 20     else
 21       x=tot++;
 22     sh[x].sz=sh[x].val=sh[x].sum=sh[x].res=sh[x].lx=sh[x].rx=sh[x].tx=sh[x].vc=0;
 23     sh[x].son[0]=sh[x].son[1]=sh[x].sf=sh[x].fa=0;
 24     sh[x].vc=inf;
 25     return x;
 26 }
 27 void clear(int x)
 28 {
 29     q.push(x);
 30     if (sh[x].son[0]) clear(sh[x].son[0]);
 31     if (sh[x].son[1]) clear(sh[x].son[1]);
 32 }
 33 void connect(int x,int y,int dir)//x->y
 34 {
 35     sh[y].son[dir]=x;
 36     sh[x].fa=y;
 37     sh[x].sf=dir;
 38 }
 39 void pushdown(int x)
 40 {
 41     int ls,rs;
 42     ls=sh[x].son[0];rs=sh[x].son[1];
 43     if (sh[x].res==1)
 44     {
 45         if (ls)
 46         {
 47             sh[sh[ls].son[0]].sf^=1;sh[sh[ls].son[1]].sf^=1;
 48             swap(sh[ls].son[0],sh[ls].son[1]);
 49             swap(sh[sh[ls].son[0]].lx,sh[sh[ls].son[0]].rx);
 50             swap(sh[sh[ls].son[1]].lx,sh[sh[ls].son[1]].rx);
 51             sh[ls].res^=1;
 52         }
 53         if (rs)
 54         {
 55             sh[sh[rs].son[0]].sf^=1;sh[sh[rs].son[1]].sf^=1;
 56             swap(sh[rs].son[0],sh[rs].son[1]);
 57             swap(sh[sh[rs].son[0]].lx,sh[sh[rs].son[0]].rx);
 58             swap(sh[sh[rs].son[1]].lx,sh[sh[rs].son[1]].rx);
 59             sh[rs].res^=1;
 60         }
 61         sh[x].res=0;
 62     }
 63     if (sh[x].vc!=inf)
 64     {
 65         if (ls)
 66         {
 67             sh[ls].val=sh[ls].vc=sh[x].vc;
 68             sh[ls].sum=sh[ls].val*sh[ls].sz;
 69             sh[ls].tx=max(sh[ls].val,sh[ls].val*sh[ls].sz);
 70             sh[ls].lx=sh[ls].rx=max(0,sh[ls].val*sh[ls].sz);
 71         }
 72         if (rs)
 73         {
 74             sh[rs].val=sh[rs].vc=sh[x].vc;
 75             sh[rs].sum=sh[rs].val*sh[rs].sz;
 76             sh[rs].tx=max(sh[rs].val,sh[rs].val*sh[rs].sz);
 77             sh[rs].lx=sh[rs].rx=max(0,sh[rs].val*sh[rs].sz);
 78         }
 79         sh[x].vc=inf;
 80     }
 81 }
 82 void pushup(int x)
 83 {
 84     int ls,rs;
 85     ls=sh[x].son[0];rs=sh[x].son[1];
 86     sh[x].sz=sh[ls].sz+sh[rs].sz+1;
 87     sh[x].sum=sh[ls].sum+sh[rs].sum+sh[x].val;
 88     sh[x].lx=max(sh[ls].lx,sh[ls].sum+sh[rs].lx+sh[x].val);
 89     sh[x].rx=max(sh[rs].rx,sh[rs].sum+sh[ls].rx+sh[x].val);
 90     sh[x].tx=max(sh[ls].tx,max(sh[rs].tx,sh[ls].rx+sh[rs].lx+sh[x].val));
 91 }
 92 void rotate(int x)
 93 {
 94     int fa,gf,son,xd,fd;
 95     fa=sh[x].fa;gf=sh[sh[x].fa].fa;
 96     xd=sh[x].sf;fd=sh[fa].sf;
 97     son=sh[x].son[xd^1];
 98     connect(x,gf,fd);connect(fa,x,xd^1);connect(son,fa,xd);
 99     sh[0].fa=sh[0].son[0]=sh[0].son[1]=sh[0].sf=0;
100     pushup(fa);pushup(x);
101 }
102 void splay(int x,int y)
103 {
104     while (sh[x].fa!=y)
105     {
106         if (sh[sh[x].fa].fa==y)
107           rotate(x);
108         else
109         if (sh[x].sf==sh[sh[x].fa].sf)
110         {
111             rotate(sh[x].fa);
112             rotate(x);
113         }
114         else
115         {
116             rotate(x);
117             rotate(x);
118         }
119     }
120     if (y==0)
121       root=x;
122 }
123 int find(int x,int k)
124 {
125     pushdown(x);
126     if (k>sh[sh[x].son[0]].sz+1)
127       return find(sh[x].son[1],k-sh[sh[x].son[0]].sz-1);
128     if (k<=sh[sh[x].son[0]].sz)
129       return find(sh[x].son[0],k);
130     return x;
131 }
132 int build(int l,int r,int father,int dir)
133 {
134     int mid=(l+r)>>1;
135     int x=newnode();
136     sh[x].val=a[mid];
137     sh[x].fa=father;sh[x].sf=dir;
138     if (l==r)
139     {
140         sh[x].sz=1;
141         sh[x].sum=sh[x].tx=a[mid];
142         sh[x].lx=sh[x].rx=max(0,a[mid]);
143         return x;
144     }
145     if (l<=mid-1)
146       sh[x].son[0]=build(l,mid-1,x,0);
147     if (r>=mid+1)
148       sh[x].son[1]=build(mid+1,r,x,1);
149     pushup(x);
150     return x;
151 }
152 int split(int l,int r)
153 {
154     int per,suc;
155     per=find(root,l);suc=find(root,r+2);
156     splay(per,0);
157     splay(suc,per);
158     return sh[suc].son[0];
159 }
160 int main()
161 {
162     scanf("%d%d",&n,&m);
163     for (int i=1;i<=n;i++)
164       scanf("%d",&a[i]);
165     tot=1;sh[0].tx=a[0]=a[n+1]=-inf;
166     root=build(0,n+1,0,0);
167     while (m--)
168     {
169         char ch[20];
170         scanf("%s",ch);
171         if (ch[0]=='I')
172         {
173             int pos,tot;
174             scanf("%d%d",&pos,&tot);
175             for (int i=1;i<=tot;i++)
176               scanf("%d",&a[i]);
177             int x=build(1,tot,0,0);
178             int A,B;
179             A=find(root,pos+1);B=find(root,pos+2);
180             splay(A,0);splay(B,A);
181             connect(x,B,0);
182             pushup(B);pushup(A);
183         }
184         if (ch[0]=='D')
185         {
186             int pos,tot;
187             scanf("%d%d",&pos,&tot);
188             int per,suc;
189             per=find(root,pos);suc=find(root,pos+tot+1);
190             splay(per,0);
191             splay(suc,per);
192             clear(sh[suc].son[0]);
193             sh[suc].son[0]=0;
194             pushup(suc);pushup(per);
195         }
196         if (ch[0]=='M' && ch[2]=='K')
197         {
198             int pos,tot,c;
199             scanf("%d%d%d",&pos,&tot,&c);
200             int x=split(pos,pos+tot-1);
201             sh[x].val=sh[x].vc=c;
202             sh[x].sum=c*sh[x].sz;
203             sh[x].tx=max(sh[x].val,c*sh[x].sz);
204             sh[x].lx=sh[x].rx=max(0,c*sh[x].sz);
205             pushup(sh[x].fa);pushup(sh[sh[x].fa].fa);
206         }
207         if (ch[0]=='R')
208         {
209             int pos,tot;
210             scanf("%d%d",&pos,&tot);
211             int x=split(pos,pos+tot-1);
212             sh[x].res^=1;
213             int ls,rs;
214             ls=sh[x].son[0];rs=sh[x].son[1];
215             sh[ls].sf^=1;sh[rs].sf^=1;
216             swap(sh[x].son[0],sh[x].son[1]);
217             swap(sh[ls].lx,sh[ls].rx);
218             swap(sh[rs].lx,sh[rs].rx);
219             pushup(x);pushup(sh[x].fa);pushup(sh[sh[x].fa].fa);
220         }
221         if (ch[0]=='G')
222         {
223             int pos,tot;
224             scanf("%d%d",&pos,&tot);
225             int x=split(pos,pos+tot-1);
226             printf("%d\n",sh[x].sum);
227         }
228         if (ch[0]=='M' && ch[2]=='X')
229         {
230             printf("%d\n",sh[root].tx);
231         }
232     }
233 }
维护数列

3.可持久化线段树

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=2*1e5+100;
 4 int n,m,a[N],b[N],tr[N];
 5 int root[N],cnt;
 6 struct node
 7 {
 8     int ls,rs,sz;
 9 }sh[N*40];
10 int ask(int a)
11 {
12     int pos;
13     pos=lower_bound(b+1,b+1+n,a)-b;
14     return pos;
15 }
16 void pushup(int x)
17 {
18     int ls,rs;
19     ls=sh[x].ls;rs=sh[x].rs;
20     sh[x].sz=sh[ls].sz+sh[rs].sz;
21 }
22 int build(int &x,int l,int r)
23 {
24     if (!x) x=++cnt;
25     if (l==r) return x;
26     int mid=(l+r)>>1;
27     sh[x].ls=build(sh[x].ls,l,mid);
28     sh[x].rs=build(sh[x].rs,mid+1,r);
29     pushup(x);
30     return x;
31 }
32 int change(int x,int l,int r,int wh)
33 {
34     int p=++cnt;
35     sh[p]=sh[x];
36     if (l==r)
37     {
38         sh[p].sz++;
39         return p;
40     }
41     int mid=(l+r)>>1;
42     if (wh<=mid) sh[p].ls=change(sh[x].ls,l,mid,wh);
43     else sh[p].rs=change(sh[x].rs,mid+1,r,wh);
44     pushup(p);
45     return p;
46 }
47 int query(int lx,int rx,int l,int r,int k)
48 {
49     if (l==r) return l;
50     int lz,mid;
51     mid=(l+r)>>1;
52     lz=sh[sh[rx].ls].sz-sh[sh[lx].ls].sz;
53     if (k<=lz) return query(sh[lx].ls,sh[rx].ls,l,mid,k);
54     else return query(sh[lx].rs,sh[rx].rs,mid+1,r,k-lz);
55 }
56 int main()
57 {
58     scanf("%d%d",&n,&m);
59     for (int i=1;i<=n;i++)
60       scanf("%d",&a[i]);
61     for (int i=1;i<=n;i++) b[i]=a[i];
62     sort(b+1,b+1+n);
63     for (int i=1;i<=n;i++)
64     {
65         int pos=lower_bound(b+1,b+1+n,a[i])-b;
66         tr[pos]=a[i];
67         a[i]=pos;
68     }
69     root[0]=build(root[0],1,n);
70     for (int i=1;i<=n;i++)
71       root[i]=change(root[i-1],1,n,a[i]);
72     while (m--)
73     {
74         int l,r,k;
75         scanf("%d%d%d",&l,&r,&k);
76         printf("%d\n",tr[query(root[l-1],root[r],1,n,k)]);
77     }
78 }
主席树
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e6+100;;
 4 int n,m,root[N],a[N];
 5 int cnt;
 6 struct node
 7 {
 8     int ls,rs,val;
 9 }sh[N*40];
10 int build(int &x,int l,int r)
11 {
12     if (!x) x=++cnt;
13     if (l==r)
14     {
15         sh[x].val=a[l];
16         return x;
17     }
18     int mid=(l+r)>>1;
19     sh[x].ls=build(sh[x].ls,l,mid);
20     sh[x].rs=build(sh[x].rs,mid+1,r);
21     return x;
22 }
23 int change(int x,int l,int r,int wh,int v)
24 {
25     int p=++cnt;
26     sh[p]=sh[x];
27     if (l==r)
28     {
29         sh[p].val=v;
30         return p;
31     }
32     int mid=(l+r)>>1;
33     if (wh<=mid) sh[p].ls=change(sh[x].ls,l,mid,wh,v);
34     else sh[p].rs=change(sh[x].rs,mid+1,r,wh,v);
35     return p;
36 }
37 int query(int x,int l,int r,int wh)
38 {
39     if (l==r) return sh[x].val;
40     int mid=(l+r)>>1;
41     if (wh<=mid) return query(sh[x].ls,l,mid,wh);
42     else return query(sh[x].rs,mid+1,r,wh);
43 }
44 int main()
45 {
46     scanf("%d%d",&n,&m);
47     for (int i=1;i<=n;i++)
48       scanf("%d",&a[i]);
49     root[0]=build(root[0],1,n);
50     for (int i=1;i<=m;i++)
51     {
52         int ver,op,loc;
53         scanf("%d%d%d",&ver,&op,&loc);
54         if (op==1)
55         {
56             int v;
57             scanf("%d",&v);
58             root[i]=change(root[ver],1,n,loc,v);
59         }
60         if (op==2)
61         {
62             root[i]=root[ver];
63             printf("%d\n",query(root[ver],1,n,loc));
64         }
65     }
66 }
可持久化数组
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+100,M=2*1e5+100;
 4 int n,m,fa[N],root[M],cnt;
 5 struct node
 6 {
 7     int ls,rs,val,deep;
 8 }sh[N*40];
 9 int build(int &x,int l,int r)
10 {
11     if (!x) x=++cnt;
12     if (l==r)
13     {
14         sh[x].val=fa[l];
15         return x;
16     }
17     int mid=(l+r)>>1;
18     sh[x].ls=build(sh[x].ls,l,mid);
19     sh[x].rs=build(sh[x].rs,mid+1,r);
20     return x;
21 }
22 int change(int x,int l,int r,int wh,int v)
23 {
24     int p=++cnt;
25     sh[p]=sh[x];
26     if (l==r)
27     {
28         sh[p].val=v;
29         return p;
30     }
31     int mid=(l+r)>>1;
32     if (wh<=mid) sh[p].ls=change(sh[x].ls,l,mid,wh,v);
33     else sh[p].rs=change(sh[x].rs,mid+1,r,wh,v);
34     return p;
35 }
36 void change_depth(int x,int l,int r,int wh)
37 {
38     if (l==r)
39     {
40         sh[x].deep++;
41         return;
42     }
43     int mid=(l+r)>>1;
44     if (wh<=mid) change_depth(sh[x].ls,l,mid,wh);
45     else change_depth(sh[x].rs,mid+1,r,wh);
46 }
47 int query(int x,int l,int r,int wh,int kind)
48 {
49     if (l==r) return (kind==1)?sh[x].val:sh[x].deep;
50     int mid=(l+r)>>1;
51     if (wh<=mid) return query(sh[x].ls,l,mid,wh,kind);
52     else return query(sh[x].rs,mid+1,r,wh,kind);
53 }
54 int find(int x,int &root)
55 {
56     int father=query(root,1,n,x,1);
57     if (x==father) return x;
58     return find(father,root);
59 }
60 int main()
61 {
62     scanf("%d%d",&n,&m);
63     for (int i=1;i<=n;i++) fa[i]=i;
64     root[0]=build(root[0],1,n);
65     for (int i=1;i<=m;i++)
66     {
67         int op;
68         scanf("%d",&op);
69         if (op==1)
70         {
71             int a,b,Fa,Fb,da,db;
72             scanf("%d%d",&a,&b);
73             root[i]=root[i-1];
74             Fa=find(a,root[i]);Fb=find(b,root[i]);
75             da=query(root[i],1,n,Fa,0);db=query(root[i],1,n,Fb,0);
76             if (Fa==Fb) continue;
77             if (da>db) swap(Fa,Fb);
78             root[i]=change(root[i],1,n,Fa,Fb);
79             change_depth(root[i],1,n,Fb);
80         }
81         if (op==2)
82         {
83             int k;
84             scanf("%d",&k);
85             root[i]=root[k];
86         }
87         if (op==3)
88         {
89             int a,b,Fa,Fb;
90             scanf("%d%d",&a,&b);
91             root[i]=root[i-1];
92             Fa=find(a,root[i]);
93             Fb=find(b,root[i]);
94             if (Fa==Fb) printf("1\n");
95             else printf("0\n");
96         }
97     }
98 }
可持久化并查集

4.数论分块

 1 #include <bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 int n,k;
 5 signed main()
 6 {
 7     scanf("%lld%lld",&n,&k);
 8     int ans=n*k;
 9     for (int i=1;i<=n;)
10     {
11         int t,j;
12         t=k/i;
13         j=(t!=0)?min(k/t,n):n;
14         ans-=t*(i+j)*(j-i+1)/2;
15         i=j+1;
16     }
17     printf("%lld\n",ans);
18 }
数论分块

5.树形背包

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=310;
 4 int n,m,s[N],dp[N][N],sz[N];
 5 vector <int> e[N];
 6 void dfs(int x)
 7 {
 8     dp[x][0]=0;
 9     for (int i=0;i<(int)e[x].size();i++)
10     {
11         int u=e[x][i];
12         dfs(u);
13         for (int j=m+1;j>0;j--)
14         {
15             for (int k=0;k<j;k++)
16               dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[u][k]);
17         }
18     }
19 }
20 int main()
21 {
22     scanf("%d%d",&n,&m);
23     for (int i=1;i<=n;i++)
24     {
25         int k;
26         scanf("%d%d",&k,&s[i]);
27         dp[i][1]=s[i];
28         e[k].push_back(i);
29     }
30     dfs(0);
31     printf("%d\n",dp[0][m+1]);
32 }
dfs合并
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=310;
 4 int n,m,s[N],dp[N][N],d[N],dfn[N],cnt;
 5 int nxt[N];
 6 vector <int> e[N];
 7 void dfs(int x)
 8 {
 9     dfn[x]=cnt++;
10     for (int i=0;i<(int)e[x].size();i++)
11     {
12         int u=e[x][i];
13         dfs(u);
14     }
15     nxt[dfn[x]]=cnt;
16 }
17 int main()
18 {
19     scanf("%d%d",&n,&m);
20     for (int i=1;i<=n;i++)
21     {
22         int k;
23         scanf("%d%d",&k,&s[i]);
24         e[k].push_back(i);
25     }
26     dfs(0);
27     memset(dp,-0x3f,sizeof(dp));
28     memset(dp[0],0,sizeof(dp[0]));
29     for (int i=1;i<=n;i++) d[dfn[i]]=s[i];
30     for (int i=0;i<=n;i++)
31     {
32         for (int j=0;j<=min(i,m+1);j++)
33         {
34             dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+d[i]);
35             dp[nxt[i]][j]=max(dp[nxt[i]][j],dp[i][j]);
36         }
37     }
38     printf("%d\n",dp[n+1][m+1]);
39 }
dfs序

6.线段树合并

  1 #include <bits/stdc++.h>
  2 #define m_k make_pair
  3 using namespace std;
  4 const int N=100100;
  5 int n,m,tot,cnt,first[N],nxt[N*2],point[N*2];
  6 int fa[N][21],de[N],root[N],MAX,ans[N];
  7 vector <pair<int,int> > q[N];
  8 struct node
  9 {
 10     int ls,rs,MAX,id;
 11 }sh[N*50];
 12 void add_edge(int x,int y)
 13 {
 14     tot++;
 15     nxt[tot]=first[x];
 16     first[x]=tot;
 17     point[tot]=y;
 18 }
 19 void dfs(int x,int father)
 20 {
 21     fa[x][0]=father;
 22     for (int i=first[x];i!=-1;i=nxt[i])
 23     {
 24         int u=point[i];
 25         if (u==father) continue;
 26         de[u]=de[x]+1;
 27         dfs(u,x);
 28     }
 29 }
 30 int lca(int a,int b)
 31 {
 32     if (de[a]>de[b]) swap(a,b);
 33     for (int i=20;i>=0;i--)
 34     {
 35         if (de[fa[b][i]]>=de[a])
 36           b=fa[b][i];
 37     }
 38     if (a==b) return a;
 39     for (int i=20;i>=0;i--)
 40     {
 41         if (fa[a][i]!=fa[b][i])
 42         {
 43             a=fa[a][i];
 44             b=fa[b][i];
 45         }
 46     }
 47     return fa[a][0];
 48 }
 49 void pushup(int x)
 50 {
 51     int ls,rs;
 52     ls=sh[x].ls;rs=sh[x].rs;
 53     sh[x].MAX=max(sh[ls].MAX,sh[rs].MAX);
 54     if (sh[ls].MAX==sh[rs].MAX) sh[x].id=min(sh[ls].id,sh[rs].id);
 55     if (sh[ls].MAX<sh[rs].MAX) sh[x].id=sh[rs].id;
 56     if (sh[ls].MAX>sh[rs].MAX) sh[x].id=sh[ls].id;
 57 }
 58 void change(int &x,int l,int r,int co,int s)
 59 {
 60     if (!x) x=++cnt;
 61     if (l==r)
 62     {
 63         sh[x].MAX+=s;sh[x].id=co;
 64         return;
 65     }
 66     int mid=(l+r)>>1;
 67     if (co<=mid) change(sh[x].ls,l,mid,co,s);
 68     else change(sh[x].rs,mid+1,r,co,s);
 69     pushup(x);
 70 }
 71 int merge(int a,int b,int l,int r)
 72 {
 73     if (!a) return b;
 74     if (!b) return a;
 75     if (l==r)
 76     {
 77         sh[a].MAX+=sh[b].MAX;
 78         return a;
 79     }
 80     int mid=(l+r)>>1;
 81     sh[a].ls=merge(sh[a].ls,sh[b].ls,l,mid);
 82     sh[a].rs=merge(sh[a].rs,sh[b].rs,mid+1,r);
 83     pushup(a);
 84     return a;
 85 }
 86 void dfs1(int x)
 87 {
 88     for (int i=first[x];i!=-1;i=nxt[i])
 89     {
 90         int u=point[i];
 91         if (u==fa[x][0]) continue;
 92         dfs1(u);
 93     }
 94     root[x]=++cnt;
 95     for (int i=0;i<(int)q[x].size();i++)
 96       change(root[x],1,MAX,q[x][i].first,q[x][i].second);
 97     for (int i=first[x];i!=-1;i=nxt[i])
 98     {
 99         int u=point[i];
100         if (u==fa[x][0]) continue;
101         root[x]=merge(root[x],root[u],1,MAX);
102     }
103     ans[x]=sh[root[x]].MAX?sh[root[x]].id:0;
104 }
105 int main()
106 {
107     tot=-1;
108     memset(nxt,-1,sizeof(nxt));
109     memset(first,-1,sizeof(first));
110     scanf("%d%d",&n,&m);
111     for (int i=1;i<n;i++)
112     {
113         int x,y;
114         scanf("%d%d",&x,&y);
115         add_edge(x,y);
116         add_edge(y,x);
117     }
118     dfs(1,1);
119     for (int j=1;j<=20;j++)
120     {
121         for (int i=1;i<=n;i++)
122           fa[i][j]=fa[fa[i][j-1]][j-1];
123     }
124     for (int i=1;i<=m;i++)
125     {
126         int a,b,c,l;
127         scanf("%d%d%d",&a,&b,&c);
128         l=lca(a,b);
129         q[a].push_back(m_k(c,1));
130         q[b].push_back(m_k(c,1));
131         q[l].push_back(m_k(c,-1));
132         if (l!=1) q[fa[l][0]].push_back(m_k(c,-1));
133         MAX=max(MAX,c);
134     }
135     dfs1(1);
136     for (int i=1;i<=n;i++) printf("%d\n",ans[i]);
137 }
雨天的尾巴

7.fhq_treap

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int MAXN=100100;
  4 int n,root,t;
  5 struct node
  6 {
  7     int val,key,si,son[2],g;
  8 }sh[MAXN];
  9 deque <int> q;
 10 int newnode(int v)
 11 {
 12     t++;
 13     sh[t].si=sh[t].g=1;
 14     sh[t].val=v;
 15     sh[t].key=rand();
 16     return t;
 17 }
 18 void pushup(int x)
 19 {
 20     sh[x].si=sh[x].g+sh[sh[x].son[0]].si+sh[sh[x].son[1]].si;
 21 }
 22 void split(int now,int k,int &x,int &y)
 23 {
 24     if (now==0)
 25     {
 26         x=y=0;
 27         return;
 28     }
 29     if (sh[now].val<=k)
 30     {
 31         x=now;
 32         split(sh[now].son[1],k,sh[now].son[1],y);
 33     }
 34     else
 35     {
 36         y=now;
 37         split(sh[now].son[0],k,x,sh[now].son[0]);
 38     }
 39     pushup(now);
 40 }
 41 int merge(int x,int y)
 42 {
 43     if (x==0)
 44       return y;
 45     if (y==0)
 46       return x;
 47     if (sh[x].key<sh[y].key)
 48     {
 49         sh[x].son[1]=merge(sh[x].son[1],y);
 50         pushup(x);
 51         return x;
 52     }
 53     else
 54     {
 55         sh[y].son[0]=merge(x,sh[y].son[0]);
 56         pushup(y);
 57         return y;
 58     }
 59 }
 60 int kth(int now,int k)
 61 {
 62     if (sh[sh[now].son[0]].si<k && k<=sh[sh[now].son[0]].si+sh[now].g)
 63       return now;
 64     else
 65     if (k<sh[sh[now].son[0]].si+sh[now].g)
 66       return kth(sh[now].son[0],k);
 67     else
 68       return kth(sh[now].son[1],k-sh[sh[now].son[0]].si-sh[now].g);
 69 }
 70 int find(int x)
 71 {
 72     q.clear();
 73     int cur;
 74     cur=root;
 75     while (sh[cur].son[x>sh[cur].val]!=0 && sh[cur].val!=x)
 76       q.push_back(cur),cur=sh[cur].son[x>sh[cur].val];
 77     q.push_back(cur);
 78     return cur;
 79 }
 80 void updata()
 81 {
 82     while (!q.empty())
 83     {
 84         pushup(q.back());
 85         q.pop_back();
 86     }
 87 }
 88 int main()
 89 {
 90     srand(time(0));
 91     root=0;
 92     scanf("%d",&n);
 93     for (int i=1;i<=n;i++)
 94     {
 95         int x,op;
 96         scanf("%d%d",&op,&x);
 97         if (op==1)
 98         {
 99             int cur=find(x);
100             if (sh[cur].val==x)
101             {
102                 sh[cur].g++;
103                 updata();
104             }
105             else
106             {
107                 int a,b;
108                 split(root,x,a,b);
109                 root=merge(merge(a,newnode(x)),b);
110             }
111         }
112         if (op==2)
113         {
114             int cur=find(x);
115             sh[cur].g--;
116             updata();
117             if (sh[cur].g==0)
118             {
119                 int a,b,c;
120                 split(root,x,a,b);
121                 split(a,x-1,a,c);
122                 c=merge(sh[c].son[0],sh[c].son[1]);
123                 root=merge(merge(a,b),c);
124             }
125         }
126         if (op==3)
127         {
128             int a,b;
129             split(root,x-1,a,b);
130             printf("%d\n",sh[a].si+1);
131             root=merge(a,b);
132         }
133         if (op==4)
134         {
135             printf("%d\n",sh[kth(root,x)].val);
136         }
137         if (op==5)
138         {
139             int a,b;
140             split(root,x-1,a,b);
141             printf("%d\n",sh[kth(a,sh[a].si)].val);
142             root=merge(a,b);
143         }
144         if (op==6)
145         {
146             int a,b;
147             split(root,x,a,b);
148             printf("%d\n",sh[kth(b,1)].val);
149             root=merge(a,b);
150         }
151     }
152 }
fhq_treap

8.BSGS

 1 #include <bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 int p,b,n,sp;
 5 map <int,int> t;
 6 int m_pow(int a,int b)
 7 {
 8     int ans=1;
 9     while (b)
10     {
11         if (b&1) ans=(ans*a)%p;
12         b>>=1;
13         a=(a*a)%p;
14     }
15     return ans;
16 }
17 int inv(int x)
18 {
19     return m_pow(x,p-2);
20 }
21 int bsgs()
22 {
23     sp=sqrt(p);
24     int x=1;
25     for (int i=0;i<sp;i++)
26     {
27         t[x]=i;
28         if (x==n) return i;
29         x=(x*b)%p;
30     }
31     for (int i=2;i<=sp;i++)
32     {
33         int div=m_pow(b,sp*(i-1));
34         div=inv(div);
35         x=(n*div)%p;
36         if (t[x]) return t[x]+sp*(i-1);
37     }
38     return -1;
39 }
40 signed main()
41 {
42     scanf("%lld%lld%lld",&p,&b,&n);
43     if (n==0)
44     {
45         printf("1\n");
46         return 0;
47     }
48     int ans=bsgs();
49     if (ans==-1) printf("no solution\n");
50     else printf("%lld\n",ans);
51 }
BSGS

9.exCRT/CRT

 1 #include <bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 const int N=1e5+100;
 5 int n,a[N],b[N];
 6 int mul(int a,int b,int mod)
 7 {
 8     bool bl=0;
 9     if (a<0) bl^=1;
10     if (b<0) bl^=1;
11     a=abs(a);b=abs(b);
12     int ans=0;
13     while (b)
14     {
15         if (b&1ll) ans=(ans+a)%mod;
16         b>>=1ll;
17         a=(a+a)%mod;
18     }
19     return (bl)?-ans:ans;
20 }
21 int gcd(int a,int b)
22 {
23     if (b==0) return a;
24     else return gcd(b,a%b);
25 }
26 void exgcd(int a,int b,int &x,int &y)
27 {
28     if (b==0)
29     {
30         x=1;y=0;
31         return;
32     }
33     exgcd(b,a%b,x,y);
34     int z=x;
35     x=y;y=z-(a/b)*y;
36 }
37 int lcm(int a,int b)
38 {
39     int g=gcd(a,b);
40     return (a/g)*b;
41 }
42 int work(int a,int b,int c)
43 {
44     int g=gcd(a,b);
45     a/=g;b/=g;c/=g;
46     int x,y;
47     exgcd(a,b,x,y);
48     x=mul(x,c,b);x=(x%b+b)%b;
49     return x;
50 }
51 signed main()
52 {
53     scanf("%lld",&n);
54     for (int i=1;i<=n;i++)
55       scanf("%lld%lld",&a[i],&b[i]);
56     for (int i=2;i<=n;i++)
57     {
58         int x=work(a[1],a[i],b[i]-b[1]);
59         int na=a[1];
60         a[1]=lcm(a[1],a[i]);
61         b[1]=(mul(na,x,a[1])+b[1])%a[1];
62         // b[1]=a[1]*x+b[1];
63     }
64     printf("%lld\n",b[1]);
65 }
CRT

10.Miller Robin素数测试

 1 #include <bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 int n;
 5 int p[8]={2,3,5,7,11,13,17,47};
 6 int mul(int a,int b,int mod)
 7 {
 8     int ans=0;
 9     while (b)
10     {
11         if (b&1) ans=(ans+a)%mod;
12         b>>=1;
13         a=(a+a)%mod;
14     }
15     return ans;
16 }
17 int m_pow(int a,int b,int mod)
18 {
19     int ans=1;
20     while (b)
21     {
22         if (b&1) ans=mul(ans,a,mod);
23         b>>=1;
24         a=mul(a,a,mod);
25     }
26     return ans;
27 }
28 bool miller_robin(int n,int a)
29 {
30     int d,r;
31     d=n-1;r=0;
32     while (d%2==0)
33     {
34         d>>=1;
35         r++;
36     }
37     int now=m_pow(a,d,n);
38     if (now==1) return true;
39     for (int i=0;i<r;i++)
40     {
41         if (now==n-1) return true;
42         now=mul(now,now,n);
43     }
44     return false;
45 }
46 bool check(int n)
47 {
48     if (n<2) return false;
49     for (int i=0;i<8;i++)
50     {
51         if (n==p[i]) return true;
52         if (n%p[i]==0) return false;
53         if (!miller_robin(n,p[i]) && n>p[i]) return false;
54     }
55     return true;
56 }
57 signed main()
58 {
59     scanf("%lld",&n);
60     if (check(n)) printf("Prime\n");
61     else printf("Not Prime\n");
62 }
Miller Robin

 

posted @ 2020-01-21 15:30  SevenDawns  阅读(122)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end