NOIP模板总结

NOIP模板总结

  进考场先打一份缺省源:

  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 int main()
13 {
14 
15     return 0;
16 }
缺省源
  
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int n=0;
 6     while(1)
 7     {
 8         printf("Test %d:\n",++n);
 9         system("data.exe");
10         system("my.exe");
11         system("std.exe");
12         if(system("fc std.out my.out"))
13             puts("WA"),system("pause");
14         else puts("AC");
15     }
16 }
对拍
  
1 # define r(a,b) (rand()*rand()%((b)-(a)+1)+(a))
生成随机数
  
1 int read()
2 {
3     int x=0,f=1;
4     char c=getchar();
5     while(!isdigit(c)) { if(c=='-') f=-f; c=getchar(); }
6     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
7     return x*f;
8 }
快读

  重启一下电脑看看是哪些盘不清空。

调配置:

  ·工具->编译选项->代码警告->显示最多警告消息;

  ·工具->编译选项->连接器->产生调试信息;

  ·(如果$IDE$右边有奇怪的白色竖线):工具->编辑器属性->基本->右边缘->把勾去掉;

  ·工具->编辑器属性->高亮显示当前行->$Green$;

  ·工具->编辑器属性->显示->字体:$Andalus$->大小$10$;

  ·工具->编辑器属性->语法->预设$Obsidian$;

  虽然比不上$Vscode$漂亮,但是至少挺清楚的.

  本来想把数据结构都封装成结构体,后来发现没什么用处还容易错...等联赛完了再弄这些东西吧。

  前几篇模板都是全套的,大多数还在$OJ$上交过,后面的一些来不及写了只写了主要的函数,但是思路肯定是对的.

图论:

  关于最小生成树,实测还是$kruscal$比较快,而且内存小,而且代码短.

  
1 for (R k=1;k<=n;++k)
2     for (R i=1;i<=n;++i)
3         for (R j=1;j<=n;++j)
4             g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
5             
floyd
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <queue>
 4 # include <cstring>
 5 # define ll long long
 6 # define R register int
 7 # define pac(a,b) make_pair(a,b)
 8 
 9 using namespace std;
10 
11 const int maxn=100005;
12 const int maxm=200005;
13 int n,m,s,h,firs[maxn],vis[maxn],x,y,z;
14 ll d[maxn];
15 struct edge
16 {
17     int too,nex,co;
18 }g[maxm<<1];
19 typedef pair <int,int> pii;
20 priority_queue <pii,vector<pii>,greater<pii> >q;
21 
22 void add (int x,int y,int z)
23 {
24     g[++h].nex=firs[x];
25     firs[x]=h;
26     g[h].too=y;
27     g[h].co=z;
28 }
29 
30 int read()
31 {
32     int x=0;
33     char c=getchar();
34     while(!isdigit(c)) c=getchar();
35     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
36     return x;
37 }
38 
39 void dij (int s)
40 {
41     int beg,j;
42     memset(d,1,sizeof(d));
43     d[s]=0;
44     q.push(pac(0,s));
45     while(q.size())
46     {
47         beg=q.top().second;
48         q.pop();
49         if(vis[beg]) continue;
50         vis[beg]=true;
51         for (R i=firs[beg];i;i=g[i].nex)
52         {
53             j=g[i].too;
54             if(d[beg]+g[i].co>=d[j]) continue;
55             d[j]=d[beg]+g[i].co;
56             q.push(pac(d[j],j));
57         }
58     }
59 }
60 
61 int main()
62 {
63     n=read(),m=read(),s=read();
64     for (R i=1;i<=m;++i)
65     {
66         x=read(),y=read(),z=read();
67         add(x,y,z);
68     }
69     dij(s);
70     for (R i=1;i<=n;++i)
71         printf("%lld ",d[i]);
72     return 0;
73 }
Heap+dijkstra
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <queue>
 4 # include <cstring>
 5 # define ll long long
 6 # define R register int
 7 # define pac(a,b) make_pair(a,b)
 8 
 9 using namespace std;
10 
11 const int maxn=100005;
12 const int maxm=200005;
13 int n,m,s,h,firs[maxn],vis[maxn],x,y,z;
14 ll d[maxn],f[maxn];
15 struct edge
16 {
17     int too,nex,co;
18 }g[maxm<<1];
19 typedef pair <int,int> pii;
20 priority_queue <pii,vector<pii>,greater<pii> >q;
21 
22 void add (int x,int y,int z)
23 {
24     g[++h].nex=firs[x];
25     firs[x]=h;
26     g[h].too=y;
27     g[h].co=z;
28 }
29 
30 int read()
31 {
32     int x=0;
33     char c=getchar();
34     while(!isdigit(c)) c=getchar();
35     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
36     return x;
37 }
38 
39 void dij (int s)
40 {
41     int beg,j;
42     memset(d,1,sizeof(d));
43     d[s]=0;
44     f[s]=1;
45     q.push(pac(0,s));
46     while(q.size())
47     {
48         beg=q.top().second;
49         q.pop();
50         if(vis[beg]) continue;
51         vis[beg]=true;
52         for (R i=firs[beg];i;i=g[i].nex)
53         {
54             j=g[i].too;
55             if(d[beg]+g[i].co>d[j]) continue;
56             if(d[beg]+g[i].co==d[j]) f[j]+=f[beg];
57             else
58             {
59                 f[j]=f[beg];
60                 d[j]=d[beg]+g[i].co;
61                 q.push(pac(d[j],j));
62             }
63         }
64     }
65 }
66 
67 int main()
68 {
69     n=read(),m=read(),s=read();
70     for (R i=1;i<=m;++i)
71     {
72         x=read(),y=read(),z=read();
73         add(x,y,z);
74     }
75     dij(s);
76     for (R i=1;i<=n;++i)
77         printf("%lld ",f[i]);
78     return 0;
79 }
最短路计数
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <queue>
 4 # include <cstring>
 5 # define ll long long
 6 # define R register int
 7 
 8 using namespace std;
 9 
10 const int maxn=100005;
11 const int maxm=200005;
12 int n,m,s,h,firs[maxn],vis[maxn],x,y,z;
13 ll d[maxn],f[maxn];
14 struct edge
15 {
16     int too,nex,co;
17 }g[maxm<<1];
18 queue <int> q;
19 
20 void add (int x,int y,int z)
21 {
22     g[++h].nex=firs[x];
23     firs[x]=h;
24     g[h].too=y;
25     g[h].co=z;
26 }
27 
28 int read()
29 {
30     int x=0;
31     char c=getchar();
32     while(!isdigit(c)) c=getchar();
33     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
34     return x;
35 }
36 
37 void spfa (int s)
38 {
39     int beg,j;
40     memset(d,1,sizeof(d));
41     d[s]=0;
42     q.push(s);
43     while(q.size())
44     {
45         beg=q.front();
46         q.pop();
47         vis[beg]=false;
48         for (R i=firs[beg];i;i=g[i].nex)
49         {
50             j=g[i].too;
51             if(d[beg]+g[i].co>d[j]) continue;
52         d[j]=d[beg]+g[i].co;
53         if(!vis[j]) q.push(j),vis[j]=true;
54         }
55     }
56 }
57 
58 int main()
59 {
60     n=read(),m=read(),s=read();
61     for (R i=1;i<=m;++i)
62     {
63         x=read(),y=read(),z=read();
64         add(x,y,z);
65     }
66     spfa(s);
67     for (R i=1;i<=n;++i)
68         printf("%lld ",d[i]);
69     return 0;
70 }
spfa
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <queue>
 6 # define R register int
 7 # define ll long long
 8 # define pac(a,b) make_pair(a,b)
 9 
10 using namespace std;
11 
12 const int maxn=5003;
13 const int maxm=200005;
14 int n,m,h,firs[maxn],d[maxn],vis[maxn],x,y,z,ed[maxn];
15 struct edge
16 {
17     int too,nex,co;
18 }g[maxm<<1];
19 typedef pair <int,int> pii;
20 priority_queue <pii,vector<pii>,greater<pii> > q;
21 
22 void add (int x,int y,int z)
23 {
24     g[++h].nex=firs[x];
25     firs[x]=h;
26     g[h].too=y;
27     g[h].co=z;
28 }
29 
30 int main()
31 {
32     scanf("%d%d",&n,&m);
33     for (R i=1;i<=m;++i)
34     {
35         scanf("%d%d%d",&x,&y,&z);
36         add(x,y,z);
37         add(y,x,z);
38     }
39     memset(d,1,sizeof(d));
40     vis[1]=0,d[1]=0;
41     q.push(pac(0,1));
42     int j,beg;
43     while(q.size())
44     {
45         beg=q.top().second;
46         q.pop();
47         if(vis[beg]) continue;
48         vis[beg]=true;
49         for (R i=firs[beg];i;i=g[i].nex)
50         {
51             j=g[i].too;
52             if(vis[j]) continue;
53             d[j]=min(d[j],g[i].co);
54             q.push(pac(d[j],j));
55         }
56     }
57     for (R i=1;i<=n;++i)
58         if(!vis[j]) 
59         {
60             printf("orz");
61             return 0;
62         }
63     int ans=0;
64     for (R i=1;i<=n;++i)
65         ans+=d[i];
66     printf("%d",ans);
67     return 0;
68 }
Heap+Prim
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # define R register int
 7 # define ll long long
 8 
 9 using namespace std;
10 
11 const int maxn=5003;
12 const int maxm=200005;
13 int n,m,h,f[maxn],z[maxn],S,fx,fy,ans;
14 struct ed
15 {
16     int x,y,z;
17 }g[maxm];
18 
19 bool cmp (ed a,ed b) { return a.z<b.z; }
20 int father (int x) { if(x!=f[x]) return f[x]=father(f[x]); return x; }
21 
22 int main()
23 {
24     scanf("%d%d",&n,&m);
25     for (R i=1;i<=m;++i)
26         scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].z);
27     sort(g+1,g+1+m,cmp);
28     for (R i=1;i<=n;++i)
29         f[i]=i,z[i]=1;
30     S=n;
31     for (R i=1;i<=m;++i)
32     {
33         fx=father(g[i].x);
34         fy=father(g[i].y);
35         if(fx==fy) continue;
36         ans+=g[i].z;
37         if(z[fx]>z[fy]) z[fx]+=z[fy],f[fy]=fx;
38         else z[fy]+=z[fx],f[fx]=fy;
39         S--;
40     }
41     if(S!=1) printf("orz");
42     else printf("%d",ans);
43     return 0;
44 }
Kruskal
  
 1     差分约束其实还是最短路,考的主要是一些建图:
 2         如果给出的式子有的是小于有的是大于,要先移项后再做;
 3     举个栗子:a[i]-a[j]<=c -> a[i]<=a[j]+c
 4     可以认为做一遍最短路后a[j]向a[i]连一条边权为c的边无法更新dis[i],所以连边后跑最短路;
 5     如果图不保证联通可以加一个虚点向其他所有点连边,边权视情况而定.
 6     一些基本的性质题目可能不说,但是自己要记得写:a[i]全为正时,s[i]>s[i-1],etc...
 7     求最大值跑最短路,最小值跑最长路.
 8     如果有负权边就只能用spfa,无解一般表现为又负环或者正环,用spfa判断.
 9     虽然很假,但是考场上要是真的不会做了可以考虑"梦想spfa",即运行时间过长时直接认为是负环.
10     板子就不写了,和最短路差不多的.
差分约束
  
 1 bool spfa()
 2 {
 3     memset(d,0x3f,sizeof(d));
 4     int j,beg;
 5     while (q.size()) q.pop();
 6     q.push(1);
 7     d[1]=0;
 8     while (q.size())
 9     {
10         beg=q.front();
11         q.pop();
12         vis[beg]=0;
13         for (int i=firs[beg];i;i=g[i].nex)
14         {
15             j=g[i].too;
16             if(d[j]>d[beg]+g[i].co)
17             {
18                 d[j]=d[beg]+g[i].co;
19                 s[j]=s[beg]+1;
20                 if(s[j]>=n) return 1;
21                 if(!vis[j])
22                 {
23                     vis[j]=1;
24                     q.push(j);
25                 }
26             }
27         }
28     }
29     return 0;
30 }
31 判断负环的方法很多,有时dfs的确实快,但是那个的复杂度根本不对,所以建议还是写这个。普通的spfa也有两种写法,一种是记录到每个点的最短路经过了几个点,还有一种是记录每个点入队几次,也许两者一起用是最好的吧,这里给出第一种做法。
spfa判负环
  
 1 void init()
 2 {
 3     for (R i=2;i<=n;++i) lg[i]=lg[i>>1]+1;
 4 }
 5 
 6 void dfs (int x)
 7 {
 8     int j;
 9     for (R i=firs[x];i;i=g[i].nex)
10     {
11         j=g[i].too;
12         if(dep[j]) continue;
13         dep[j]=dep[x];
14         f[j][0]=x;
15         for (R k=1;k<=lg[ dep[j] ];++k)
16             f[j][k]=f[ f[j][k-1] ][k-1];
17         dfs(j);
18     }
19 }
20 
21 int lca (int x,int y)
22 {
23     if(dep[x]>dep[y]) swap(x,y);
24     for (R i=lg[ dep[y] ];i>=0;--i)
25         if(dep[y]-(1<<i)>=dep[x]) y=f[y][i];
26     if(x==y) return x;
27     for (R i=lg[ dep[x] ];i>=0;--i)
28     {
29         if(f[x][i]=f[y][i]) continue;
30         x=f[x][i];
31         y=f[y][i];
32     }
33     return f[x][0];
34 }
倍增求LCA
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # define R register int
 4 
 5 using namespace std;
 6 
 7 int n,m,h,firs[maxn],r[maxn],c[maxn],x,y;
 8 struct edge
 9 {
10     略去.
11 };
12 
13 void dfs (int x)
14 {
15     int j,t;
16     for (R &i=firs[x];i;i=g[i].nex) //这个&是优化时间复杂度的精髓所在啊!
17     {
18         if(vis[i]) continue;
19         j=g[i].too;
20         vis[i]=true;
21         t=i;
22         dfs(j);
23         sta[++top]=t; //因为之前加过取地址符,所以i可能变了 :(
24     }
25 }
26 
27 int main()
28 {
29     scanf("%d%d",&n,&m);
30     for (R i=1;i<=m;++i)
31     {
32         scanf("%d%d",&x,&y);
33         r[x]++,c[y]++;
34         add(x,y);
35     }
36     for (R i=1;i<=n;++i)
37         if(r[i]!=c[i])
38         {
39             printf("NO");
40             return 0;
41         }
42     for (R i=1;i<=n;++i) //图中可能有一些孤立点,但是因为欧拉回路的关键是边所以没有关系
43         if(firs[i])
44         {
45             dfs(i);
46             break;
47         }
48     for (R i=Top;i>=1;--i) printf("%d ",sta[i]);
49     return 0;
50 }
欧拉回路-有向图
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # define R register int
 4 
 5 using namespace std;
 6 
 7 int n,m,h,firs[maxn],r[maxn],c[maxn],x,y;
 8 struct edge
 9 {
10     略去.
11 };
12 
13 void dfs (int x)
14 {
15     int j,ID;
16     for (R &i=firs[x];i;i=g[i].nex) //这个&是优化时间复杂度的精髓所在啊!
17     {
18         ID=g[i].id;
19         if(ID<0) ID=-ID;
20         if(vis[ ID ]) continue;
21         j=g[i].too;
22         vis[ ID ]=true;
23         dfs(j);
24         sta[++top]=ID; //因为之前加过取地址符,所以i可能变了 :(
25     }
26 }
27 
28 int main()
29 {
30     scanf("%d%d",&n,&m);
31     for (R i=1;i<=m;++i)
32     {
33         scanf("%d%d",&x,&y);
34         d[x]++,d[y]++;
35         add(x,y,i);
36         add(y,x,-i);
37     }
38     for (R i=1;i<=n;++i)
39         if(d[i]%2)
40         {
41             printf("NO");
42             return 0;
43         }
44     for (R i=1;i<=n;++i) //图中可能有一些孤立点,但是因为欧拉回路的关键是边所以没有关系
45         if(firs[i])
46         {
47             dfs(i);
48             break;
49         }
50     for (R i=Top;i>=1;--i) printf("%d ",sta[i]);
51     return 0;
52 }
欧拉回路-无向图
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <cmath>
 6 # include <algorithm>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=100005;
13 const int maxm=200005;
14 int n,m,x,y,h,firs[maxn],d[maxn],f[maxn],z[maxn],od[maxn];
15 struct edge
16 {
17     int too,nex;
18 }g[maxm<<1];
19 
20 int father (int x) { if(x!=f[x]) return f[x]=father(f[x]); return x; }
21 
22 inline void uni (int x,int y)
23 {
24     int fx=father(x);
25     int fy=father(y);
26     if(fx==fy) return ;
27     if(z[fx]>z[fy]) f[fy]=fx,z[fx]+=z[fy];
28     else f[fx]=fy,z[fy]+=z[fx];
29 }
30 
31 int main()
32 {
33     while(scanf("%d%d",&n,&m)!=EOF)
34     {
35         h=1;
36         memset(d,0,sizeof(d));
37         memset(firs,0,sizeof(firs));
38         memset(od,0,sizeof(od));
39         for (R i=1;i<=n;++i) f[i]=i,z[i]=1;
40         for (R i=1;i<=m;++i)
41         {
42             scanf("%d%d",&x,&y);
43             d[x]++,d[y]++;
44             uni(x,y);
45         }
46         for (R i=1;i<=n;++i) f[i]=father(i);        
47         for (R i=1;i<=n;++i) if(d[i]&1) od[ f[i] ]++;
48         int ans=0;
49         for (R i=1;i<=n;++i)
50             if(f[i]==i&&z[i]!=1) ans+=max(1,od[i]/2);
51         printf("%d\n",ans);
52     }
53     return 0;
54 }
有向图最少笔画数
  
1 欧拉道路就是把每条边不重不漏的经过一次的道路啦。
2 无向图:1.图连通;
3        2.有0/2个奇点;
4 
5 有向图:1:图连通;
6        2:所有点的入度出度均相等或一点的入度比出度大一,一点入度比出度小一。
欧拉道路相关
  
 1 void dfs (int x,int f)
 2 {
 3     id[x]=low[x]=++cnt;
 4     int j,son_cnt=0;
 5     for (R i=firs[x];i;i=g[i].nex)
 6     {
 7         j=g[i].too;
 8         if(!id[j])
 9         {
10             dfs(j,x);
11             son_cnt++;
12             low[x]=min(low[x],low[j]);
13             if(low[j]>=id[x]) cutt[x]=true;
14         }
15         else low[x]=min(low[x],id[j]);
16     }
17     if(f==0&&son_cnt>=2) cutt[x]=true;
18 }
Tarjan-割点
  
 1 void dfs (int x,int las)
 2 {
 3     id[x]=low[x]=++cnt;
 4     int j,son_cnt=0;
 5     for (R i=firs[x];i;i=g[i].nex)
 6     {
 7         if(i==(las^1)) continue;
 8         j=g[i].too;
 9         if(!id[j])
10         {
11             dfs(j,i);
12             low[x]=min(low[x],low[j]);
13             if(low[j]>id[x]) g[i].t=t[i^1].t=1;
14         }
15         else
16             low[x]=min(low[x],id[j]);
17     }
18 }
Tarjan-桥
  
 1 void dfs (int x)
 2 {
 3     id[x]=low[x]=++cnt;
 4     vis[x]=true;
 5     sta[++Top]=x;
 6     int j;
 7     for (R i=firs[x];i;i=g[i].nex)
 8     {
 9         j=g[i].too;
10         if(!id[j])
11         {
12             dfs(j);
13             low[x]=min(low[x],low[j]);
14         }
15         else if(vis[j]) low[x]=min(low[x],id[j]);
16     }
17     if(low[x]==id[x])
18     {
19         col[x]=++bp;
20         vis[x]=0;
21         while(sta[Top]!=x)
22         {
23             col[ sta[Top] ]=bp;
24             vis[ sta[Top] ]=0;
25             Top--;
26         }
27         Top--;
28     }
29 }
Tarjan-强连通
  
1 找出桥后删掉所有的桥,每个联通块就是一个边双。
Tarjan-边双
  
 1 void dfs(int x,int f)
 2 {
 3     id[x]=low[x]=++cnt;
 4     int j,sz=0,k;
 5     for (R i=firs[x];i;i=g[i].nex)
 6     {
 7         j=g[i].too;
 8         if(!id[j])
 9         {
10             sz++,sta[++Top]=i;
11             dfs(j,x);
12             low[x]=min(low[j],low[x]);
13             if(low[j]>=id[x])
14             {
15                 v[x]=true;
16                 bp++;
17                 do
18                 {
19                     k=sta[Top];
20                     if(col[ g[k].fro ]!=bp)
21                     {
22                         col[ g[k].fro ]=bp;
23                         v_dcc[bp].push_back(g[k].fro);
24                         siz[bp]++;
25                     }
26                     if(col[ g[k].too ]!=bp)
27                     {
28                         col[ g[k].too ]=bp;
29                         v_dcc[bp].push_back(g[k].too);
30                         siz[bp]++;
31                     }
32                     Top--;
33                 }while(k!=i);
34             }
35         }else low[x]=min(low[x],id[j]);
36     }
37     if(f==0&&sz<=1) v[x]=false;
38 }
Tarjan-点双

dp优化:

  注意矩阵乘法时一定要把$k$写在最外层循环,因为每次访问的内存连续所以可以快很多,真的快很多!

  
 1 struct mat
 2 {
 3     int n,m;
 4     ll a[maxn][maxn];
 5     void init()
 6     {
 7         memset(a,0,sizeof(a));
 8         for (R i=0;i<5;++i)
 9             a[i][i]=1;
10     }
11     void cler() { memset(a,0,sizeof(a)); }
12     mat operator *  (const mat &a) const
13     {
14         mat c;
15         c.cler();
16         for (R k=0;k<a.m;++k)
17             for (R i=0;i<this->n;++i)
18                 for (R j=0;j<this->m;++j)    
19                     c.a[i][j]=(c.a[i][j]+this->a[i][k]*a.a[k][j]%m)%m;
20         c.n=n;
21         c.m=a.m;
22         return c;
23     }
24 };
25 
26 mat qui (mat a,int p)
27 {
28     mat ans;
29     ans.init();
30     ans.n=ans.m=5;
31     while(p)
32     {
33         if(p&1) ans=ans*a;
34         a=a*a;
35         p>>=1;
36     }
37     return ans;
38 }
矩阵快速幂
  
 1 ll X (int i) { return ; }
 2 ll Y (int i) { return ; }
 3 ll K (int i) { return ; }
 4 ll B (int i) { return ; }
 5 double KK (int a,int b) {    if(X(b)==X(a)) return 0; return (double)(Y(b,j)-Y(a,j))/(X(b)-X(a));    }
 6 
 7 struct xq
 8 {
 9     int q[maxn];
10     int h,t;
11     void ins (int i)
12     {
13         int a,b,c;
14         if(h<t) a=q[t-1],b=q[t],c=i;
15         while(h<t&&KK(a,b)>KK(a,c))
16         {
17             t--;
18             if(h<t) a=q[t-1],b=q[t],c=i;
19         }
20         q[++t]=i;
21     }
22     void del (int i)
23     {
24         int a,b;
25         if(h<t) a=q[h],b=q[h+1];
26         while(h<t&&KK(a,b)<K(i))
27         {
28             h++;
29             if(h<t) a=q[h],b=q[h+1];    
30         }    
31     }
32     void init() { h=1,t=0; }
33     int firs () { return q[h]; }
34 }q;
基于单调队列的斜率优化

 

数论算法:

  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 ll a,b,p;
13 
14 int main()
15 {
16     scanf("%lld%lld%lld",&a,&b,&p);
17     ll s=1;
18     while(b)
19     {
20         if(b&1LL) s=s*a%p;
21         a=a*a%p;
22         b=b>>1;
23     }
24     printf("%lld\n",s%p);
25     return 0;
26 }
快速幂
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 ll a,b,p;
13 
14 int main()
15 {
16     scanf("%lld%lld%lld",&a,&b,&p);
17     ll s=0;
18     while(b)
19     {
20         if(b&1LL) s=s+a%p;
21         a=a+a%p;
22         b=b>>1;
23     }
24     printf("%lld\n",s%p);
25     return 0;
26 }
快速加
  
1 int ad (int a,int b)
2 {
3     a+=b;
4     if(a>=p) a-=p;
5     return a;
6 }
加法取模优化
  
1 inv[1]=1;
2 for (R i=2;i<=n;++i)
3     inv[i]=(mod-mod/i)*inv[mod%i]%mod;
线性求逆元
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=10000007;
13 int f[maxn],pri[maxn],h;
14 
15 void sieve()
16 {
17     f[1]=1;
18     for (R i=2;i<=n;++i)
19     {
20         if(!f[i]) pri[++h]=i;
21         for (R j=1;j<=h&&i*pri[j]<=n;++j)
22         {
23             f[ i*pri[j] ]=1;
24             if(i%pri[j]==0) break;
25         }
26     }
27 }
28 
29 int main()
30 {
31 
32     return 0;
33 }
线性筛素数
  
1 void sdiv (int x)
2 {
3     for (R i=2;i*i<=n;++i)
4     {
5         if(x%i==0) p[++h]=i;
6         while(x%i==0) c[h]++,x/=i;
7     }
8     if(x!=1) p[h]=x,c[h]=1;
9 }
根号时间分解质因数
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=10000007;
13 int f[maxn],pri[maxn],h,m[maxn],a[maxn];
14 
15 void ldiv (int x)
16 {
17     int cnt=0;
18     while(x!=1)
19     {
20         a[++cnt]=m[x];
21         x/=m[x];
22     }
23 }
24 
25 void sieve()
26 {
27     f[1]=1;
28     for (R i=2;i<=n;++i)
29     {
30         if(!f[i]) pri[++h]=i,m[i]=i;
31         for (R j=1;j<=h&&i*pri[j]<=n;++j)
32         {
33             f[ i*pri[j] ]=1;
34             m[ i*pri[j] ]=pri[j];
35             if(i%pri[j]==0) break;
36         }
37     }
38 }
39 
40 int main()
41 {
42     sieve();
43     return 0;
44 }
log时间分解质因数
  
 1 f[1]=1,phi[1]=1;
 2 for(re int i=2;i<=n;i++)
 3 {
 4     if(!f[i]) p[++p[0]]=i,phi[i]=i-1;
 5     for(re int j=1;j<=p[0]&&p[j]*i<=n;j++)
 6     {
 7         f[p[j]*i]=1;
 8         if(i%p[j]==0)
 9         {
10             phi[p[j]*i]=phi[i]*p[j];
11             break;
12         }
13         phi[p[j]*i]=phi[i]*(p[j]-1);
14     }
15 }
16 这个是抄的asuldb的.
欧拉筛
  
1 int gcd (int a,int b) { return b?gcd(b,a%b):a; }
gcd
  
 1 int gcd (int a,int b)
 2 {
 3     int p=1;
 4     if(a<b) swap(a,b);
 5     while(a&&b)
 6     {
 7         if(a%2==0&&b%2==0) p*=2,a/=2,b/=2;
 8         else if(a%2&&b%2==0) b/=2;
 9         else if(a%2==0&&b%2) a/=2;
10         else a-=b;
11         if(a<b) swap(a,b);
12     }
13     return p*a;
14 }
Stein算法求gcd
  
  1 # include <cstdio>
  2 # include <iostream>
  3 # include <cstring>
  4 # include <string>
  5 # define R register int
  6 
  7 using namespace std;
  8 
  9 const int maxn=10005;
 10 const int base=1e8;
 11 char c[maxn];
 12 struct big
 13 {
 14     int a[maxn];
 15     int len;
 16     void write()
 17     {
 18         printf("%d",a[len]);
 19         for (R i=len-1;i>=1;--i)
 20             printf("%08d",a[i]);
 21         if(len==0) printf("0");
 22     }
 23     void div()
 24     {
 25         int mod=0;
 26         for (R i=len;i>=1;--i)
 27         {
 28             a[i]+=mod*base;
 29             mod=a[i]%2;
 30             a[i]/=2;
 31         }
 32         while (a[ len ]==0&&len) len--;
 33     }
 34     void clear()
 35     {
 36         memset(a,0,sizeof(a));
 37         len=0;
 38     }
 39     void mul()
 40     {
 41         for (R i=1;i<=len;++i)
 42             a[i]*=2;
 43         for (R i=1;i<=len+1;++i)
 44             a[i+1]+=a[i]/base,a[i]%=base;
 45         len++;
 46         while (a[ len ]==0&&len) len--;
 47     }
 48     bool operator < (const big &b) const
 49     {
 50         if(b.len!=len) return len<b.len;
 51         for (R i=len;i>=1;--i)
 52             if(b.a[i]==a[i]) continue;
 53             else return a[i]<b.a[i];
 54         return false;
 55     }
 56     void read()
 57     {
 58         scanf("%s",c+1);
 59         int l=strlen(c+1);
 60         len=l/8+((l%8)?1:0);
 61         int x=0,pos=0;
 62         for (R i=1;i<=l;++i)
 63         {
 64             x=x*10+c[i]-'0';
 65             if(i%8==l%8)
 66             {
 67                 a[ len-pos ]=x;
 68                 pos++;
 69                 x=0;
 70             }
 71         }
 72         if(x) a[len-pos]=x;
 73     }
 74 }A,B;
 75 
 76 void sub()
 77 {
 78     for (R i=1;i<=B.len;++i)
 79     {
 80         A.a[i]-=B.a[i];
 81         if(A.a[i]<0) A.a[i]+=base,A.a[i+1]--;
 82     }
 83     while (A.a[ A.len ]==0&&A.len) A.len--;
 84 }
 85 
 86 void gcd ()
 87 {
 88     int cnt=0;
 89     if(A<B) swap(A,B);
 90     while (A.len&&B.len)
 91     {
 92         if(A.a[1]%2==0&&B.a[1]%2==0) cnt++,A.div(),B.div();
 93         else if (A.a[1]%2&&B.a[1]%2==0) B.div();
 94         else if (A.a[1]%2==0&&B.a[1]%2) A.div();
 95         else sub();
 96         if(A<B) swap(A,B);
 97     }
 98     for (R i=1;i<=cnt;++i)
 99         A.mul();
100     A.write();
101 }
102 
103 int main()
104 {
105     A.read();
106     B.read();
107        gcd();
108     return 0;
109 }
压位高精实现Stein算法
  
 1 void exgcd (int a,int b,int &x,int &y)
 2 {
 3     if(b==0)
 4     {
 5         x=1,y=0;
 6         return;
 7     }
 8     exgcd(b,a%b,y,x);
 9     y-=a/b*x;
10 }
exgcd
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # define R register int
 6 # define ll long long
 7 
 8 using namespace std;
 9 
10 const int maxn=10000;
11 int a[maxn],b[maxn];
12 char c[maxn];
13 
14 int main()
15 {
16     scanf("%s",c+1);
17     a[0]=strlen(c+1);
18     for (R i=1;i<=a[0];++i)
19         a[i]=c[ a[0]-i+1 ]-'0';
20     scanf("%s",c+1);
21     b[0]=strlen(c+1);
22     for (R i=1;i<=b[0];++i)
23         b[i]=c[ b[0]-i+1 ]-'0';
24     a[0]=max(a[0],b[0])+1;
25     for (R i=1;i<=a[0];++i)
26     {
27         a[i]+=b[i];
28         a[i+1]+=a[i]/10;
29         a[i]%=10;
30     }
31     while(a[ a[0] ]==0&&a[0]) a[0]--;
32     for (R i=a[0];i>=1;--i)
33         printf("%d",a[i]);
34     if(a[0]==0) printf("0");
35     return 0;
36 }
高精度加法
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # define R register int
 6 # define ll long long
 7 
 8 using namespace std;
 9 
10 const int maxn=10005;
11 int a[maxn],b[maxn];
12 char c[maxn];
13 
14 bool smaller ()
15 {
16     if(a[0]!=b[0]) return a[0]<b[0];
17     for (R i=a[0];i>=1;--i)
18         if(a[i]!=b[i]) return a[i]<b[i];
19     return false;
20 }
21 
22 void chan()
23 {
24     int n=max(a[0],b[0]);
25     for (R i=0;i<=n;++i)
26         swap(a[i],b[i]);
27 }
28 
29 int main()
30 {
31     scanf("%s",c+1);
32     a[0]=strlen(c+1);
33     for (R i=1;i<=a[0];++i)
34         a[i]=c[ a[0]-i+1 ]-'0';
35     scanf("%s",c+1);
36     b[0]=strlen(c+1);
37     for (R i=1;i<=b[0];++i)
38         b[i]=c[ b[0]-i+1 ]-'0';
39     if(smaller())
40     {
41         printf("-");
42         chan();
43     } 
44     for (R i=1;i<=a[0];++i)
45     {  
46         a[i]-=b[i];
47         if(a[i]<0) a[i]+=10,a[i+1]--;
48     }
49     while(a[ a[0] ]==0&&a[0]) a[0]--;
50     for (R i=a[0];i>=1;--i)
51         printf("%d",a[i]);
52     if(a[0]==0) printf("0");
53     return 0;
54 }
高精度减法
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # define R register int
 6 # define ll long long
 7 
 8 using namespace std;
 9 
10 const int maxn=10005;
11 int a[maxn],b[maxn],d[maxn];
12 char c[maxn];
13 
14 int main()
15 {
16     scanf("%s",c+1);
17     a[0]=strlen(c+1);
18     for (R i=1;i<=a[0];++i)
19         a[i]=c[ a[0]-i+1 ]-'0';
20     scanf("%s",c+1);
21     b[0]=strlen(c+1);
22     for (R i=1;i<=b[0];++i)
23         b[i]=c[ b[0]-i+1 ]-'0';
24     d[0]=a[0]+b[0]+2;
25     for (R i=1;i<=a[0];++i)
26         for (R j=1;j<=b[0];++j)
27             d[i+j-1]+=a[i]*b[j];
28     for (R i=1;i<=d[0];++i)
29     {
30         d[i+1]+=d[i]/10;
31         d[i]%=10;
32     }
33     while(d[ d[0] ]==0&&d[0]) d[0]--;
34     for (R i=d[0];i>=1;--i)
35         printf("%d",d[i]);
36     if(d[0]==0) printf("0");
37     return 0;
38 }
高精度乘法
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # include <map>
 8 # define R register int
 9 # define ll long long
10 
11 using namespace std;
12 
13 const int maxn=100000;
14 int T,n,m,a[maxn],sta[maxn],Top;
15 char c[maxn];
16 map <char,int> m1;
17 map <int,char> m2;
18 
19 int main() //模m取余,逆序输出,除法退位位时注意上一位的余数乘n即可 
20 {
21     scanf("%d",&T);
22     for (R i=0;i<=9;++i)
23         m1[ i+'0' ]=i,m2[i]=i+'0';
24     for (R i=10;i<=35;++i)
25         m1[i-10+'A']=i,m2[i]=i-10+'A';
26     for (R i=36;i<=61;++i)
27         m1[i-36+'a']=i,m2[i]=i-36+'a';
28     while (T--)
29     {
30         scanf("%d%d",&n,&m);
31         scanf("%s",c+1);
32         a[0]=strlen(c+1);
33         Top=0;
34         for (R i=1;i<=a[0];++i)
35             a[a[0]-i+1]=m1[ c[i] ];
36         printf("%d ",n);
37         for (R i=a[0];i>=1;--i)
38             printf("%c",m2[ a[i] ]);
39         printf("\n");
40         while(a[0])
41         {
42             int r=0;
43             for (R i=a[0];i>=1;--i)
44             {
45                 a[i]=r*n+a[i];
46                 r=a[i]%m;
47                 a[i]/=m;
48             }
49             sta[++Top]=r;
50             while(a[ a[0] ]==0&&a[0]) a[0]--;
51         }
52         printf("%d ",m);
53         for (R i=Top;i>=1;--i)
54             printf("%c",m2[ sta[i] ]);
55         printf("\n\n");
56     }
57 }
高精度n进制转m进制
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # define R register int
 6 # define ll long long
 7 
 8 using namespace std;
 9 
10 const int maxn=10005;
11 int a[maxn],b;
12 char c[maxn];
13 
14 int main()
15 {
16     scanf("%s",c+1);
17     a[0]=strlen(c+1);
18     for (R i=1;i<=a[0];++i)
19         a[i]=c[ a[0]-i+1 ]-'0';
20     scanf("%d",&b);
21     ll r=0;
22     for (R i=a[0];i>=1;--i)
23     {
24         a[i]+=r*10;
25         r=a[i]%b;
26         a[i]/=b;
27     }
28     while(a[ a[0] ]==0&&a[0]) a[0]--;
29     for (R i=a[0];i>=1;--i)
30         printf("%d",a[i]);
31     if(a[0]==0) printf("0");
32     printf("\n%lld",r);
33     return 0;
34 }
高精度除法+取模

 

  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 int T;
13 ll f[100005],inv[100005];
14 ll n,m,p;
15 
16 ll c(ll n,ll m)
17 {
18     if(n<m) return 0;  
19     return (f[n]*inv[m]%p)*inv[n-m]%p;
20 }
21 
22 ll lucas(ll n,ll m)
23 {
24     if(m==0)
25         return 1;
26     else
27         return (ll)lucas(n/p,m/p)*c(n%p,m%p)%p;
28 }
29 
30 ll quick_pow(ll x,ll c)
31 {
32     ll s=1;
33     while (c)
34     {
35         if(c&1) s=s*x%p;
36         x=x*x%p;
37         c=c>>1;
38     }
39     return s%p;
40 }
41 
42 void init()
43 {
44     f[0]=inv[0]=1;
45     for (int i=1;i<p;++i)
46     {
47         f[i]=f[i-1]*i%p;
48         inv[i]=quick_pow(f[i],p-2);
49     }
50 }
51 
52 int main()
53 {
54     scanf("%d",&T);
55     while (T--)
56     {
57         scanf("%lld%lld%lld",&n,&m,&p);
58         init();
59         printf("%lld\n",lucas(n+m,m));
60     }
61     return 0;
62 }
Lucas
  
  1 # include <cstdio>
  2 # include <iostream>
  3 # define R register int
  4 # define ll long long
  5 
  6 using namespace std;
  7 
  8 ll n,m,p;
  9 int h;
 10 ll a[12];
 11 ll pr[12],po[12];
 12 ll ans=1;
 13 
 14 ll qui (ll a,ll b,ll p)
 15 {
 16     ll s=1;
 17     while (b)
 18     {
 19         if(b&1LL) s=s*a%p;
 20         a=a*a%p;
 21         b=b>>1LL;
 22     }
 23     return s;
 24 }
 25 
 26 void ex_gcd (ll a,ll b,ll &x,ll &y)
 27 {
 28     if(!b) { x=1LL,y=0LL; return ; }
 29     ex_gcd(b,a%b,y,x);
 30     y-=a/b*x;
 31 }
 32 
 33 ll inv (ll a,ll p)
 34 {
 35     ll x,y;
 36     ex_gcd(a,p,x,y);
 37     return (x%p+p)%p;
 38 }
 39 
 40 ll crt ()
 41 {
 42     ll ans=0;
 43     ll x,y,m,pri;
 44     for (R i=1;i<=h;++i)
 45     {
 46         pri=po[i];
 47         m=p/pri;
 48         m%=pri;
 49         ex_gcd(m,pri,x,y);
 50         x=(x%pri+pri)%pri;
 51         m=p/pri;
 52         x=x*m%p;
 53         ans=(ans+x*a[i])%p;
 54     }
 55     return ans;
 56 }
 57 
 58 ll fac (ll n,ll Pr,ll Po)
 59 {
 60     if(n==0) return 1;
 61     ll ans=1;
 62     for (R i=2;i<=Po;++i)
 63         if(i%Pr) ans=ans*i%Po;
 64     ans=qui(ans,n/Po,Po);
 65     for (R i=2;i<=n%Po;++i)
 66         if(i%Pr) ans=ans*i%Po;
 67     return ans*fac(n/Pr,Pr,Po)%Po;
 68     
 69 }
 70 
 71 ll C (ll n,ll m,ll Pr,ll Po)
 72 {
 73     if(m>n) return 0;
 74     ll t=0;
 75     ll a=fac(n,Pr,Po),b=fac(m,Pr,Po),c=fac(n-m,Pr,Po);
 76     for (ll i=n;i;i/=Pr) t+=i/Pr;
 77     for (ll i=m;i;i/=Pr) t-=i/Pr;
 78     for (ll i=n-m;i;i/=Pr) t-=i/Pr;
 79     return qui(Pr,t,Po)*a*inv(b,Po)%Po*inv(c,Po)%Po;
 80 }
 81 
 82 
 83 ll Lucas (ll n,ll m)
 84 {
 85     for (R i=1;i<=h;++i)
 86         a[i]=C(n,m,pr[i],po[i])%p;
 87     return crt();
 88 }
 89 
 90 void div (ll p)
 91 {
 92     for (R i=2;i*i<=p;++i)
 93     {
 94         if(p%i==0)
 95         {
 96             ++h;
 97             pr[h]=i;
 98             po[h]=1;
 99             while (p%i==0) po[h]*=i,p/=i;
100         }
101     }
102     if(p>1) pr[++h]=p,po[h]=p;
103 }
104 
105 int main()
106 {
107     scanf("%lld%lld",&n,&m);
108     scanf("%lld",&p),div(p);
109     printf("%lld",Lucas(n,m));
110     return 0;
111 }
Exlucas
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # define ll long long
 4 # define R register int
 5 
 6 using namespace std;
 7 
 8 const int maxn=100005;
 9 int n,f;
10 ll m[maxn],c[maxn],m1,m2,c1,c2,I,g,x,y;
11 
12 inline char gc() {
13     static char buf[100000],*p1,*p2;
14     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
15 }
16 ll read() {
17     ll x=0; 
18     char c=gc();
19     while(!isdigit(c)) c=gc();
20     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=gc();
21     return x;
22 }
23 
24 ll gcd (ll a,ll b) { return b?gcd(b,a%b):a; }
25 void exgcd (ll a,ll b,ll &x,ll &y)
26 {
27     if(b==0)
28     {
29         x=1,y=0;
30         return ;
31     }
32     exgcd(b,a%b,y,x);
33     y-=a/b*x;
34 }
35 ll inv (ll a,ll b)
36 {
37     ll x,y;
38     exgcd(a,b,x,y);
39     x=(x%b+b)%b;
40     if(!x) x+=b;
41     return x;
42 }
43 
44 ll mul (ll a,ll b,ll p)
45 {
46     ll s=0;
47     a=(a%p+p)%p;
48     b=(b%p+p)%p;
49     while (b)
50     {
51         if(b&1LL) s=(s+a)%p;
52         a=(a+a)%p;
53         b=b>>1LL;
54     }
55     return s%p;
56 }
57 
58 int main()
59 {
60     scanf("%d",&n);
61     f=0;
62     for (R i=1;i<=n;++i)
63         m[i]=read(),c[i]=read();
64     for (R i=2;i<=n;++i)
65     {
66         m1=m[1],m2=m[i],c1=c[1],c2=c[i];
67         exgcd(m1,m2,x,y);
68         g=gcd(m1,m2);
69         ll t=m[i]/g;
70         x=mul(x,(c2-c1)/g,t);
71         x=(x%t+t)%t;
72         c[1]=(c[1]+mul(m[1],x,m[1]*t))%(m[1]*t);
73         m[1]*=t;
74         
75     }
76     printf("%lld",(c[1]%m[1]+m[1])%m[1]);
77     return 0;
78 }
Excrt

数据结构

  
 1 # include <cstdio>
 2 # include <iostream>
 3 # define R register int
 4 
 5 using namespace std;
 6 
 7 int c[500005]={0},n;
 8 
 9 void add (int x,int v) 
10 {
11     for (R i=x;i<=n;i+=(i&(-i))) c[i]+=v;
12 }
13 
14 int ask (int x)
15 {
16     int S=0;
17     for (R i=x;i;i-=(i&(-i))) S+=c[i];
18     return S;
19 }
20 
21 int main()
22 {
23     int m,x,a,b,v;
24     scanf("%d%d",&n,&m);
25     for (R i=1;i<=n;i++)
26     {
27         scanf("%d",&v);
28         add(i,v); 
29     }
30     for (R i=1;i<=m;i++)
31     {
32         scanf("%d%d%d",&x,&a,&b);
33         if(x==1)
34             add(a,b);
35         if(x==2)
36             printf("%d\n",ask(b)-ask(a-1));
37     }
38     return 0; 
39 }
树状数组单点加区间求和
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 int n,m,x,y;
13 ll k,now,last=0;
14 ll t[500005]={0};
15 ll S=0;
16 int xx;
17 
18 void add (int x,ll y)
19 {
20     for (R i=x;i<=n;i+=(i&(-i))) t[i]+=y;
21 }
22 
23 ll ask (int x)
24 {
25     ll S=0;
26     for (R i=x;i;i-=(i&(-i))) S+=t[i];
27     return S;
28 }
29 
30 int main()
31 {
32     scanf("%d%d",&n,&m);
33     for (int i=1;i<=n;i++)
34     {
35         scanf("%lld",&now);
36         add(i,now-last);
37         last=now;
38     }
39     for (int i=1;i<=m;i++)
40     {
41         scanf("%d",&xx);
42         if(xx==1)
43         {
44             scanf("%d%d",&x,&y);
45             scanf("%lld",&k);
46             add(x,k);
47             add(y+1,-k);    
48         }
49         if (xx==2)
50         {
51             scanf("%d",&x);
52             printf("%lld\n",ask(x));
53         }
54     }
55     return 0;
56 }
树状数组区间加单点查询
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 int m,n,op,x,y,opt;
13 ll a[100004]={0},k,s1,s2;
14 ll c[100004]={0},c1[100004]={0};
15 
16 void add (ll *t,int pos,ll v)
17 {
18     for (R i=pos;i<=n;i+=(i&(-i)))
19         t[i]+=v;
20 }
21 
22 ll ask (ll *t,int pos)
23 {
24     ll ans=0;
25     for (R i=pos;i;i-=(i&(-i)))
26         ans+=t[i];
27     return ans;
28 }
29 
30 int main()
31 {
32     scanf("%d%d",&n,&m);
33     for (R i=1;i<=n;++i)
34     {
35         scanf("%lld",&a[i]);
36         add(c,i,a[i]-a[i-1]);
37         add(c1,i,(i-1)*(a[i]-a[i-1]));
38     }
39     for (R i=1;i<=m;++i)
40     {
41         scanf("%d",&opt);
42         if (op==1) 
43         {
44             scanf("%d%d%lld",&x,&y,&k);
45             add(c,x,k);
46             add(c,y+1,-k);
47             add(c1,x,k*(x-1));
48             add(c1,y+1,-k*y);
49         }
50         if (op==2)
51         {
52             scanf("%d%d",&x,&y);
53             s1=(x-1)*ask(c,x-1)-ask(c1,x-1);
54             s2=y*ask(c,y)-ask(c1,y);
55             printf("%lld\n",s2-s1);
56         }
57     }
58     return 0;
59 }
树状数组区间加区间查询
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # define R register int
 5 # define lowbit(x) (x&(-x))
 6 
 7 using namespace std;
 8 
 9 const int maxn=2050;
10 int a,b,c,d,n,m,s1,s2,s3,s4,v;
11 string st;
12 int c1[maxn][maxn],c2[maxn][maxn],c3[maxn][maxn],c4[maxn][maxn];
13 
14 inline void add(int x,int y,int v)
15 {
16     for (R i=x;i<=n;i+=lowbit(i))
17         for (R j=y;j<=m;j+=lowbit(j))
18         {
19             c1[i][j]+=v;
20             c2[i][j]+=v*x;
21             c3[i][j]+=v*y;
22             c4[i][j]+=v*x*y;
23         }
24 }
25 
26 inline int ask(int x,int y)
27 {
28     int ans=0;
29     for (R i=x;i;i-=lowbit(i))
30         for (R j=y;j;j-=lowbit(j))
31         {
32             ans+=(x+1)*(y+1)*c1[i][j];
33             ans-=(y+1)*c2[i][j];
34             ans-=(x+1)*c3[i][j];
35             ans+=c4[i][j];
36         }
37     return ans;
38 }
39 
40 int main()
41 {
42     scanf("X %d %d",&n,&m);
43     while (cin>>st)
44     {
45         if(st[0]=='L') scanf("%d%d%d%d%d",&a,&b,&c,&d,&v);
46         else    scanf("%d%d%d%d",&a,&b,&c,&d);
47         if(st[0]=='L')
48         {
49             add(a,b,v);
50             add(a,d+1,-v);
51             add(c+1,b,-v);
52             add(c+1,d+1,v);
53         }
54         else
55             printf("%d\n",ask(c,d)-ask(c,b-1)-ask(a-1,d)+ask(a-1,b-1));
56     }
57     return 0;
58 }
二维树状数组区间加区间查询
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define LL long long
 9 # define nl (n<<1)
10 # define nr (n<<1|1)
11 
12 using namespace std;
13 
14 const int maxn=100005;
15 int n,m,opt,x,y;
16 LL k,t[maxn<<2],delta[maxn<<2];
17 
18 void pushdown (int n,int l,int r)
19 {
20     int mid=(l+r)>>1;
21     LL x=delta[n];
22     delta[nl]+=x;
23     delta[nr]+=x;
24     delta[n]=0;
25     t[nl]+=(mid-l+1)*x;
26     t[nr]+=(r-mid)*x;
27 }
28 
29 void build (int n,int l,int r)
30 {
31     if(l==r)
32     {
33         scanf("%lld",&t[n]);
34         return;
35     }
36     int mid=(l+r)>>1;
37     build(nl,l,mid);
38     build(nr,mid+1,r);
39     t[n]=t[nl]+t[nr];
40 }
41 
42 void add (int n,int l,int r,int ll,int rr,LL v)
43 {
44     if(ll<=l&&r<=rr)
45     {
46         delta[n]+=v;
47         t[n]+=(r-l+1)*v;
48         return;
49     }
50     int mid=(l+r)>>1;
51     if(delta[n]) pushdown(n,l,r);
52     if(ll<=mid) add(nl,l,mid,ll,rr,v);
53     if(rr>mid)  add(nr,mid+1,r,ll,rr,v);
54     t[n]=t[nl]+t[nr];
55 }
56 
57 LL ask (int n,int l,int r,int ll,int rr)
58 {
59     if(ll<=l&&r<=rr)
60         return t[n];
61     if(delta[n]) pushdown(n,l,r);
62     int mid=(l+r)>>1;
63     LL ans=0;
64     if(ll<=mid) ans=ans+ask(nl,l,mid,ll,rr);
65     if(rr>mid)  ans=ans+ask(nr,mid+1,r,ll,rr);
66     return ans;
67 }
68 
69 int main()
70 {
71     scanf("%d%d",&n,&m);
72     build(1,1,n);
73     for (R i=1;i<=m;++i)
74     {
75         scanf("%d",&opt);
76         if(opt==1)
77         {
78             scanf("%d%d%lld",&x,&y,&k);
79             add(1,1,n,x,y,k);
80         }
81         else
82         {
83             scanf("%d%d",&x,&y);
84             printf("%lld\n",ask(1,1,n,x,y));
85         }
86     }
87     return 0;
88 }
线段树区间加区间求和
  
  1 # include <cstdio>
  2 # include <iostream>
  3 # include <cstring>
  4 # include <string>
  5 # include <algorithm>
  6 # include <cmath>
  7 # define R register int
  8 # define nl (n<<1)
  9 # define nr (n<<1|1)
 10 
 11 using namespace std;
 12 
 13 const int maxn=100005;
 14 int z,x,y,n,m,r,p,a[maxn],h,firs[maxn],dep[maxn],f[maxn],siz[maxn],son[maxn],id[maxn];
 15 int cnt,top[maxn],c[maxn],t[maxn<<2],delta[maxn<<2];
 16 struct edge
 17 {
 18     int too,nex;
 19 }g[maxn<<1];
 20 
 21 int read ()
 22 {
 23     int x=0,f=1;
 24     char c=getchar();
 25     while (!isdigit(c)) { if(c=='-') f=-f; c=getchar(); }
 26     while (isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
 27     return x*f;
 28 }
 29 
 30 void add_ed (int x,int y)
 31 {
 32     g[++h].nex=firs[x];
 33     g[h].too=y;
 34     firs[x]=h;
 35 }
 36 
 37 void dfs1 (int x)
 38 {
 39     siz[x]=1;
 40     int j,maxx=0;
 41     for (R i=firs[x];i;i=g[i].nex)
 42     {
 43         j=g[i].too;
 44         if(dep[j]) continue;
 45         dep[j]=dep[x]+1;
 46         dfs1(j);
 47         f[j]=x;
 48         siz[x]+=siz[j];
 49         if(siz[j]>maxx) maxx=siz[j],son[x]=j;
 50     }
 51 }
 52 
 53 void dfs2 (int x,int Tp)
 54 {
 55     int j;
 56     id[x]=++cnt;
 57     c[cnt]=a[x];
 58     top[x]=Tp;
 59     if(!son[x]) return;
 60     dfs2(son[x],Tp);
 61     for (R i=firs[x];i;i=g[i].nex)
 62     {
 63         j=g[i].too;
 64         if(j==f[x]||j==son[x]) continue;
 65         dfs2(j,j);
 66     }
 67 }
 68 
 69 void build (int n,int l,int r)
 70 {
 71     if(l==r)
 72         t[n]=c[l]%p;
 73     else
 74     {
 75         int mid=(l+r)>>1;
 76         build(nl,l,mid);
 77         build(nr,mid+1,r);
 78         t[n]=(t[nl]+t[nr])%p;
 79     }
 80 }
 81 
 82 void pushdown (int n,int l,int r)
 83 {
 84     int mid=(l+r)>>1,x=delta[n];
 85     delta[n]=0;
 86     delta[nl]+=x;
 87     delta[nr]+=x;
 88     t[nl]=(t[nl]+1LL*x*(mid-l+1)%p)%p;
 89     t[nr]=(t[nr]+1LL*x*(r-mid)%p)%p;
 90 }
 91 
 92 void add (int n,int l,int r,int ll,int rr,int z)
 93 {
 94     if(ll<=l&&r<=rr)
 95     {
 96         delta[n]+=z;
 97         t[n]=(t[n]+1LL*z*(r-l+1)%p)%p;
 98         return;
 99     }
100     int mid=(l+r)>>1;
101     if(delta[n]) pushdown(n,l,r);
102     if(ll<=mid) add(nl,l,mid,ll,rr,z);
103     if(rr>mid) add(nr,mid+1,r,ll,rr,z);
104     t[n]=(t[nl]+t[nr])%p;
105 }
106 
107 int ask (int n,int l,int r,int ll,int rr)
108 {
109     if(ll<=l&&r<=rr) return t[n];
110     int mid=(l+r)>>1,ans=0;
111     if(delta[n]) pushdown(n,l,r);
112     if(ll<=mid) ans=(ans+ask(nl,l,mid,ll,rr))%p;
113     if(rr>mid) ans=(ans+ask(nr,mid+1,r,ll,rr))%p;
114     return ans;
115 }
116 
117 void add_link (int x,int y,int z)
118 {
119     z%=p;
120     while(top[x]!=top[y])
121     {
122         if(dep[ top[x] ]>dep[ top[y] ]) swap(x,y);
123         add(1,1,n,id[ top[y] ],id[y],z);
124         y=f[ top[y] ];
125     }
126     if(dep[x]>dep[y]) swap(x,y);
127     add(1,1,n,id[x],id[y],z);
128 }
129 
130 int ask_link (int x,int y)
131 {
132     int ans=0;
133     while(top[x]!=top[y])
134     {
135         if(dep[ top[x] ]>dep[ top[y] ]) swap(x,y);
136         ans=(ans+ask(1,1,n,id[ top[y] ],id[y]))%p;
137         y=f[ top[y] ];
138     }
139     if(dep[x]>dep[y]) swap(x,y);
140     ans=(ans+ask(1,1,n,id[x],id[y]))%p;
141     return ans;
142 }
143 
144 void add_st (int x,int z)
145 {
146     z%=p;
147     add(1,1,n,id[x],id[x]+siz[x]-1,z);
148 }
149 
150 int ask_st (int x)
151 {
152     return ask(1,1,n,id[x],id[x]+siz[x]-1);
153 }
154 
155 int main()
156 {
157     n=read(),m=read(),r=read(),p=read();
158     for (R i=1;i<=n;++i) a[i]=read();
159     for (R i=1;i<n;++i)
160     {
161         scanf("%d%d",&x,&y);
162         add_ed(x,y);
163         add_ed(y,x);
164     }
165     dep[r]=1;
166     dfs1(r);
167     dfs2(r,r);
168     build(1,1,n);
169     for (R i=1;i<=m;++i)
170     {
171         int opt=read();
172         if(opt==1)
173         {
174             x=read(),y=read(),z=read();
175             add_link(x,y,z);
176         }
177         else if(opt==2)
178         {
179             x=read(),y=read();
180             printf("%d\n",ask_link(x,y));
181         }
182         else if(opt==3)
183         {
184             x=read(),y=read();
185             add_st(x,y);
186         }
187         else 
188     {
189         x=read();
190         printf("%d\n",ask_st(x));
191         }
192     }
193     return 0;
194 }
树链剖分
  
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cmath>
 7 #define R register int
 8 #define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=100;
13 int f[maxn]={0},z[maxn],n;
14 
15 int father(int x)
16 {
17     if (f[x]!=x) return f[x]=father(f[x]);
18     return x;
19 }
20 
21 void Union(int x, int y)
22 {
23     x=f(x);
24     y=ff(y);
25     if (x==y) return;
26     if(z[x]>z[y]) z[x]+=z[y],f[y]=x;
27     else z[y]+=z[x],f[x]=y;
28 }
29 
30 void init()
31 {
32     for (int i = 1; i <= n; i++)
33         f[i]=i,z[i]=1;
34 }
35 
36 int main()
37 {
38     scanf("%d", &n);
39     init();
40     return 0;
41 }
并查集
  
  1 # include <cstdio>
  2 # include <iostream>
  3 # include <cstring>
  4 # include <string>
  5 # include <algorithm>
  6 # include <cmath>
  7 # include <cstdlib>
  8 # define R register int
  9 # define ll long long
 10 # define inf 100000008
 11 
 12 using namespace std;
 13 
 14 const int maxn=100005;
 15 int n,opt,x;
 16 struct node
 17 {
 18     int n,r,s,v;
 19     node *ch[2];
 20     void in (int x)
 21     {
 22         n=s=1;
 23         v=x;
 24         r=rand();
 25         ch[0]=ch[1]=NULL;
 26     }
 27     void update ()
 28     {
 29         s=n;
 30         if(ch[0]) s+=ch[0]->s;
 31         if(ch[1]) s+=ch[1]->s;
 32     }
 33     int cmp (int x)
 34     {
 35         if(x==v) return -1;
 36         return x>v;
 37     }
 38 }*roo,pool[maxn];
 39 
 40 node *newnode ()
 41 {
 42     static int cnt=0;
 43     return &pool[++cnt];
 44 }
 45 
 46 void rotate (node *&n,int d)
 47 {
 48     node *k=n->ch[d];
 49     n->ch[d]=k->ch[d^1];
 50     k->ch[d^1]=n;
 51     n->update();
 52     k->update();
 53     n=k;
 54 }
 55 
 56 void ins (node *&n,int x)
 57 {
 58     if(!n) n=newnode(),n->in(x);    
 59     else
 60     {
 61         int d=n->cmp(x);
 62         if(d==-1) n->n++;        
 63         else
 64         {
 65             ins(n->ch[d],x);
 66             if(n->ch[d]->r > n->r) rotate(n,d);
 67         }
 68         n->update();
 69     }
 70 }
 71 
 72 void del (node *&n,int x)
 73 {
 74     if(!n) return;
 75     int d=n->cmp(x);
 76     if(d==-1)
 77     {
 78         if(n->n > 1) --n->n;
 79         else if(!n->ch[1]) n=n->ch[0];
 80         else if(!n->ch[0]) n=n->ch[1];    
 81         else
 82         {
 83             int f=(n->ch[0]->r > n->ch[1]->r)?0:1;
 84             rotate(n,f);
 85             del(n->ch[f^1],x);
 86         }
 87         
 88     }else del(n->ch[d],x);
 89     if(n) n->update();
 90 }
 91 
 92 int ask_key (node *&n,int x)
 93 {
 94     if(!n) return 1;
 95     if(n->v==x) return (n->ch[0]?n->ch[0]->s:0)+1;
 96     if(n->v<x) return (n->ch[0]?n->ch[0]->s:0)+n->n+ask_key(n->ch[1],x);
 97     return ask_key(n->ch[0],x);
 98 }
 99 
100 int ask_value (node *&n,int x)
101 {
102     if(!n||n->s<x||x<=0) return 0;
103     int s=n->ch[0]?n->ch[0]->s:0;
104     if(s<x&&x<=s+n->n) return n->v;
105     if(s>=x) return ask_value(n->ch[0],x);
106     return ask_value(n->ch[1],x-s-n->n);
107 }
108 
109 int lef (node *&n,int x)
110 {
111     if(!n) return -inf;
112     if(n->v >= x) return lef(n->ch[0],x);
113     return max(n->v,lef(n->ch[1],x)); 
114 }
115 
116 int rig (node *&n,int x)
117 {
118     if(!n) return inf;
119     if (n->v <= x) return rig(n->ch[1], x);
120     return min(n->v,rig(n->ch[0], x));
121 }
122 
123 int main()
124 {
125     scanf("%d",&n);
126     for (R i=1;i<=n;++i)
127     {
128         scanf("%d%d",&opt,&x);
129         if(opt==1) ins(roo,x);
130         else if(opt==2) del(roo,x);
131         else if(opt==3) printf("%d\n",ask_key(roo,x));
132         else if(opt==4) printf("%d\n",ask_value(roo,x));
133         else if(opt==5) printf("%d\n",lef(roo,x));
134         else printf("%d\n",rig(roo,x));
135     }
136     return 0;
137 }
Treap
  
  1 # include <cstdio>
  2 # include <iostream>
  3 # include <queue>
  4 # include <cstring>
  5 # include <string>
  6 # define R register int
  7 # define ll long long
  8 
  9 using namespace std;
 10 
 11 const int maxn=100005;
 12 int n,m,x,y,roo;
 13 struct node
 14 {
 15     int delta,ch[2],f,siz;
 16 }t[maxn];
 17 
 18 int read();
 19 
 20 inline void update (int id)
 21 {
 22     t[id].siz=t[ t[id].ch[0] ].siz+t[ t[id].ch[1] ].siz+1;
 23 }
 24 
 25 inline void lin (int x,int f,int d)
 26 {
 27     t[x].f=f;
 28     t[f].ch[d]=x;
 29 }
 30 
 31 int build (int l,int r)
 32 {
 33     if(l>r) return 0;
 34     int mid=(l+r)>>1;
 35     lin(build(l,mid-1),mid,0);
 36     lin(build(mid+1,r),mid,1);
 37     t[mid].delta=0;
 38     update(mid);
 39     return mid;
 40 }
 41 
 42 inline void pushdown (int n)
 43 {
 44     t[n].delta=0;
 45     t[ t[n].ch[0] ].delta^=1;
 46     t[ t[n].ch[1] ].delta^=1;
 47     swap(t[n].ch[0],t[n].ch[1]);
 48 }
 49 
 50 void write (int x)
 51 {
 52     if(!x) return;
 53     if(t[x].delta) pushdown(x);
 54     write(t[x].ch[0]);
 55     if(x!=1&&x!=n+2) printf("%d ",x-1);
 56     write(t[x].ch[1]);
 57 }
 58 
 59 inline int D (int x)
 60 {
 61     return x==t[ t[x].f ].ch[1];
 62 }
 63 
 64 void rotate (int x)
 65 {
 66     int f=t[x].f;
 67     if(f==roo) roo=x;
 68     int g=t[f].f;
 69     int mf=D(x),gf=D(f);
 70     int k=t[x].ch[mf^1];
 71     lin(k,f,mf),lin(f,x,mf^1),lin(x,g,gf);
 72     update(f),update(x);
 73 }
 74 
 75 void splay (int x,int g)
 76 {
 77     while(t[x].f!=g)
 78     {
 79         if(t[ t[x].f ].f==g) rotate(x);
 80         else if(D(x)==D(t[x].f)) rotate(t[x].f),rotate(x);
 81         else rotate(x),rotate(x);
 82     }
 83     update(x);
 84 }
 85 
 86 inline int find (int x)
 87 {
 88     int no=roo;
 89     x--;
 90     if(t[no].delta) pushdown(no);
 91     while (t[ t[no].ch[0] ].siz!=x)
 92     {
 93         if(t[ t[no].ch[0] ].siz<x)
 94             x-=t[ t[no].ch[0] ].siz+1,no=t[no].ch[1];
 95         else no=t[no].ch[0];
 96         if(t[no].delta) pushdown(no);
 97     }
 98     return no;
 99 }
100 
101 int main()
102 {
103     n=read(),m=read();
104     roo=build(1,n+2);
105     while(m--)
106     {
107         x=read(),y=read();
108         x=find(x);
109         splay(x,0);
110         y=find(y+2);
111         splay(y,roo);
112         t[ t[y].ch[0] ].delta^=1;
113     }
114     write(roo);
115     return 0;
116 }
117 
118 inline int read()
119 {
120     int x=0;
121     char c=getchar();
122     while (!isdigit(c)) c=getchar();
123     while (isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
124     return x;
125 }
Splay
  
  1 # include <cstdio>
  2 # include <iostream>
  3 # include <cstring>
  4 # include <string>
  5 # include <algorithm>
  6 # include <cmath>
  7 # include <cstdlib>
  8 # include <queue>
  9 # include <ctime>
 10 # define R register int
 11 # define ll long long
 12 
 13 using namespace std;
 14 
 15 const int maxn=100005;
 16 int n,m,v[maxn],h,f[maxn],x,y,k,Q,pos[maxn];
 17 char s[2];
 18 struct node
 19 {
 20     int n,v,s,r;
 21     node *ch[2];
 22     void in (int x)
 23     {
 24         n=s=1;
 25         v=x;
 26         r=rand();
 27         ch[0]=ch[1]=NULL;
 28     }
 29     int cmp (int x)
 30     {
 31         if(x==v) return -1;
 32         return x>v;
 33     }
 34     void update()
 35     {
 36         s=n;
 37         if(ch[0]) s+=ch[0]->s;
 38         if(ch[1]) s+=ch[1]->s;
 39     }
 40 }*roo[maxn],pool[maxn*50];
 41 node *q[maxn];
 42 
 43 inline int read();
 44 node *newnode();
 45 void ins (node *&node,int x);
 46 inline void mer (int x,int y);
 47 void rotate (node *&n,int d);
 48 int father (int x);
 49 int ask (node *&n,int k);
 50 
 51 void write (int x)
 52 {
 53     if(x<0) putchar('-'),write(-x);
 54     else
 55     {
 56         if(x>=10) write(x/10);
 57         putchar(x%10+'0');
 58     }
 59 }
 60 
 61 int main()
 62 {
 63     srand(time(0));
 64     n=read(),m=read();
 65     for (R i=1;i<=n;++i)
 66         x=read(),f[i]=i,ins(roo[i],x),pos[x]=i;
 67     for (R i=1;i<=m;++i)
 68     {
 69         x=read(),y=read();
 70         if(x==0||y==0) continue;
 71         mer(x,y);
 72     }
 73     Q=read();
 74     int ans=0;
 75     while (Q--)
 76     {
 77         scanf("%s",s);
 78         x=read(),y=read();
 79         if(s[0]=='Q')
 80         {
 81             
 82             x=father(x);
 83             if(roo[x]->s<y) ans=-1;
 84             else ans=pos[ ask(roo[x],y) ];
 85             write(ans);
 86             putchar('\n');
 87         }
 88         else
 89         {
 90             mer(x,y);
 91             if(x==0||y==0) continue;
 92         }
 93     }
 94     return 0;
 95 }
 96 
 97 inline int read()
 98 {
 99     int x=0;
100     char c=getchar();
101     while(!isdigit(c)) c=getchar();
102     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
103     return x;
104 }
105 
106 int father (int x) { if(x!=f[x]) return f[x]=father(f[x]); return x; }
107 
108 node *newnode()
109 {
110     static int cnt=0;
111     return &pool[++cnt];
112 }
113 
114 void ins (node *&n,int x)
115 {
116     if(!n) n=newnode(),n->in(x);
117     else
118     {
119         int d=n->cmp(x);
120         if(d==-1) ++n->n;
121         else
122         {
123             ins(n->ch[d],x);
124             if(n->ch[d]->r > n->r) rotate(n,d);
125         }
126         n->update();
127     }
128 }
129 
130 void rotate (node *&n,int d) // rotate n->ch[d] to n
131 {
132     node *k=n->ch[d];
133     n->ch[d]=k->ch[d^1];
134     k->ch[d^1]=n;
135     n->update();
136     k->update();
137     n=k;
138 }
139 
140 inline void mer (int x,int y)
141 {
142     if(roo[x]->s<roo[y]->s) swap(x,y);
143     x=father(x);
144     y=father(y);
145     if(x==y) return;
146     f[y]=x;
147     int h=1,t=0;
148     q[++t]=roo[y];
149     node *k;
150     while(h<=t)
151     {
152         k=q[h];
153         ins(roo[x],k->v);
154         if(k->ch[0]) q[++t]=k->ch[0];
155         if(k->ch[1]) q[++t]=k->ch[1];
156         h++;
157     }
158     roo[y]=roo[x];
159 }
160 
161 int ask (node *&n,int k)
162 {
163     if(!n||k<0||n->s<k) return 0;
164     int s=n->ch[0]?n->ch[0]->s:0;
165     if(s<k&&k<=n->n+s) return n->v;
166     if(s<k) return ask(n->ch[1],k-n->n-s);
167     return ask(n->ch[0],k);
168 }
启发式合并-Treap
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=200005;
13 int n,m,t[maxn<<5],ch[maxn<<5][2],v[maxn],roo[maxn],nod_cnt,l,r,k,true_value[maxn];
14 struct node { int p,v; } a[maxn];
15 
16 bool cmp (node a,node b)
17 {
18     return a.v<b.v;
19 }
20 
21 int build (int l,int r)
22 {
23     int id=++nod_cnt;
24     if(l==r)
25         return id;
26     int mid=(l+r)>>1;
27     ch[id][0]=build(l,mid);
28     ch[id][1]=build(mid+1,r);
29     return id;
30 }
31 
32 int ins (int las,int l,int r,int pos,int v)
33 {
34     int id=++nod_cnt;
35     if(l==r)
36     {
37         t[id]=t[las]+v;
38         return id;
39     }
40     int mid=(l+r)>>1;
41     ch[id][0]=ch[las][0];
42     ch[id][1]=ch[las][1];
43     if(pos<=mid) ch[id][0]=ins(ch[las][0],l,mid,pos,v);
44     else ch[id][1]=ins(ch[las][1],mid+1,r,pos,v);
45     t[id]=t[ ch[id][0] ]+t[ ch[id][1] ];
46     return id;
47 }
48 
49 int ask (int a,int b,int l,int r,int k)
50 {
51     if(l==r) return l;
52     int mid=(l+r)>>1,x;
53     x=t[ ch[b][0] ]-t[ ch[a][0] ];
54     if(x>=k) return ask(ch[a][0],ch[b][0],l,mid,k);
55     return ask(ch[a][1],ch[b][1],mid+1,r,k-x); 
56 }
57 
58 int main()
59 {
60     scanf("%d%d",&n,&m);
61     for (R i=1;i<=n;++i)
62         scanf("%d",&a[i].v),a[i].p=i;
63     sort(a+1,a+1+n,cmp);
64     int cnt=0;
65     a[0].v=a[1].v+1;
66     for (R i=1;i<=n;++i)
67     {
68         if(a[i].v!=a[i-1].v) cnt++;
69         v[ a[i].p ]=cnt;
70         true_value[cnt]=a[i].v;
71     }
72     roo[0]=build(1,n);
73     for (R i=1;i<=n;++i)
74         roo[i]=ins(roo[i-1],1,n,v[i],1);
75     for (R i=1;i<=m;++i)
76     {
77         scanf("%d%d%d",&l,&r,&k);
78         if(l>r) swap(l,r);
79         int x=ask(roo[l-1],roo[r],1,n,k);
80         printf("%d\n",true_value[x]);
81     }
82     return 0;
83 }
84 //又名根路径可持久化函数式权值线段树
主席树
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cmath>
 4 # define R register int
 5 
 6 using namespace std;
 7 
 8 const int maxn=50004;
 9 int l,r,c,opt,n,siz;
10 int a[maxn],b[maxn],delta[maxn];
11 
12 void add (int l,int r,int v)
13 {
14     if(b[l]==b[r])
15     {
16         for (R i=l;i<=r;++i)
17             a[i]+=v;
18     }
19     else
20     {
21         if(b[l]*siz-l>l-(1+b[l]*siz-siz))
22         {
23             for (R i=1+b[l]*siz-siz;i<l;++i) a[i]-=v;
24             delta[ b[l] ]+=v;
25         }
26         else
27             for (R i=l;i<=b[l]*siz;++i) a[i]+=v;
28         for (R i=b[l]+1;i<=b[r]-1;++i) delta[i]+=v;
29         if(b[r]*siz-r>r-(1+b[r]*siz-siz))
30             for (R i=1+b[r]*siz-siz;i<=r;++i) a[i]+=v;
31         else
32         {
33             for (R i=r+1;i<=b[r]*siz;++i) a[i]-=v;
34             delta[ b[r] ]+=v;
35         }
36     }
37 }
38 
39 int main()
40 {
41     scanf("%d",&n);
42     for (R i=1;i<=n;++i) scanf("%d",&a[i]);
43     siz=sqrt(n);
44     for (R i=1;i<=n;++i) b[i]=(i-1)/siz+1;
45     for (R i=1;i<=n;++i)
46     {
47         scanf("%d%d%d%d",&opt,&l,&r,&c);
48         if(opt==0)
49             add(l,r,c);
50         else
51             printf("%d\n",a[r]+delta[ b[r] ]);
52     }
53     return 0;
54 }
分块-区间加单点查询
  
  1 # include <cstdio>
  2 # include <iostream>
  3 # include <cmath>
  4 # include <algorithm>
  5 # define R register int
  6 # define ll long long
  7 # define P(i) sort(a+1+siz*(i-1),a+1+min(siz*i,n),cmp)
  8 
  9 using namespace std;
 10 
 11 const int maxn=100004;
 12 int id,n,siz,opt,l,r,c,ans;
 13 ll delta[maxn];
 14 struct dig
 15 {
 16     int b,k;
 17     ll v;
 18 }a[maxn];
 19 
 20 bool cmp (dig a,dig b) { return a.v<b.v; }
 21 
 22 void add (int l,int r,ll c)
 23 {
 24     if(a[l].b==a[r].b)
 25     {
 26         id=a[l].b;
 27         for (R i=1+siz*(id-1);i<=min(id*siz,n);++i)
 28             if(a[i].k>=l&&a[i].k<=r) a[i].v+=c;
 29         P(a[l].b);
 30     }
 31     else
 32     {
 33         id=a[l].b;
 34         for (R i=1+siz*(id-1);i<=min(siz*id,n);++i)
 35             if(a[i].k>=l&&a[i].k<=r)
 36                 a[i].v+=c;
 37         P(id);
 38         for (R i=a[l].b+1;i<=a[r].b-1;++i) delta[i]+=c;
 39         id=a[r].b;
 40         for (R i=1+siz*(id-1);i<=min(siz*id,n);++i)
 41             if(a[i].k>=l&&a[i].k<=r)
 42                 a[i].v+=c;
 43         P(id);
 44     }
 45 }
 46 
 47 int check (int x,ll c)
 48 {
 49     int l=1+siz*(x-1),r=min(n,siz*x),mid,ans=siz*(x-1);
 50     while (l<=r)
 51     {
 52         mid=r+((l-r)>>1);
 53         if(a[mid].v+delta[ a[mid].b ]<c)
 54             l=mid+1,ans=max(ans,mid);
 55         else
 56             r=mid-1;            
 57     }
 58     return ans-siz*(x-1);
 59 }
 60 
 61 int ask (int l,int r,ll c)
 62 {
 63     int ans=0,id;
 64     if(a[l].b==a[r].b)
 65     {
 66         id=a[l].b;
 67         for (R i=1+siz*(id-1);i<=min(siz*id,n);++i)
 68             if(a[i].k>=l&&a[i].k<=r&&a[i].v+delta[ a[i].b ]<c)
 69                 ans++;
 70     }
 71     else
 72     {
 73         id=a[l].b;
 74         for (R i=1+siz*(id-1);i<=min(siz*id,n);++i)
 75             if(a[i].k>=l&&a[i].k<=r&&a[i].v+delta[ a[i].b ]<c)
 76                 ans++;
 77         for (R i=a[l].b+1;i<=a[r].b-1;++i)
 78             ans+=check(i,c);    
 79         id=a[r].b;
 80         for (R i=1+siz*(id-1);i<=min(siz*id,n);++i)
 81             if(a[i].k>=l&&a[i].k<=r&&a[i].v+delta[ a[i].b ]<c)
 82                 ans++;
 83     }
 84     return ans;
 85 }
 86 
 87 int main()
 88 {
 89     scanf("%d",&n);
 90     siz=sqrt(n);
 91     for (R i=1;i<=n;++i)
 92     {
 93         scanf("%lld",&a[i].v);
 94         a[i].k=i;
 95         a[i].b=(i-1)/siz+1;
 96     }
 97     for (R i=1;i<=a[n].b;++i) P(i);
 98     for (R i=1;i<=n;++i)
 99     {
100         scanf("%d%d%d%d",&opt,&l,&r,&c);
101         if(opt)
102         {            
103             ans=ask(l,r,1LL*c*c);
104             printf("%d\n",ans);
105         }
106         else 
107             add(l,r,c);
108     }
109     return 0;
110 }
分块-区间加区间排名
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cmath>
 4 # include <algorithm>
 5 # define R register int
 6 
 7 using namespace std;
 8 
 9 const int maxn=50004;
10 int n,b[maxn],opt,l,r,c,siz;
11 long long a[maxn],delta[maxn],s[maxn];
12 
13 void add (int l,int r,int c)
14 {
15     if(b[l]==b[r]) for (R i=l;i<=r;++i) a[i]+=c,s[ b[i] ]+=c;
16     else
17     {
18         for (R i=l;i<=siz*b[l];++i) a[i]+=c,s[ b[i] ]+=c;
19         for (R i=b[l]+1;i<=b[r]-1;++i) delta[i]+=c,s[i]+=siz*c;
20         for (R i=1+siz*(b[r]-1);i<=r;++i) a[i]+=c,s[ b[i] ]+=c;
21     }
22 }
23 
24 int ask (int l,int r,int mod)
25 {
26     long long ans=0;
27     if(b[l]==b[r]) for (R i=l;i<=r;++i) ans=(ans+a[i]+delta[ b[i] ])%mod;
28     else
29     {
30         for (R i=l;i<=siz*b[l];++i) ans=(ans+a[i]+delta[ b[i] ])%mod;
31         for (R i=b[l]+1;i<=b[r]-1;++i) ans=(ans+s[i])%mod;
32         for (R i=1+siz*(b[r]-1);i<=r;++i) ans=(ans+a[i]+delta[ b[i] ])%mod;
33     }
34     return ans%mod;
35 }
36 
37 int main()
38 {
39     scanf("%d",&n);
40     siz=sqrt(n);
41     for (R i=1;i<=n;++i) scanf("%lld",&a[i]);
42     for (R i=1;i<=n;++i) b[i]=(i-1)/siz+1,s[ b[i] ]+=a[i];
43     for (R i=1;i<=n;++i)
44     {
45         scanf("%d%d%d%d",&opt,&l,&r,&c);
46         if(opt) printf("%d\n",ask(l,r,c+1));
47         else add(l,r,c);
48     }
49     return 0;
50 }
分块-区间加区间查询
  
 1 void init()
 2 {
 3     for (R i=1;i<=n;++i)
 4         st[i][0]=read();
 5     for (R k=1;k<=lg[n];++k)
 6         for (R i=1;i+(1<<k)-1<=n;++i)
 7             st[i][k]=max(st[i][k-1],st[i+(1<<(k-1))][k-1]);
 8 }
 9 
10 int ask (int a,int b)
11 {
12     int k=lg[b-a+1];
13     return max(st[a][k],st[b-(1<<k)+1][k]);
14 }
st表

 

制胡窜

  好像$NOIP$从来没有考过真正的字符串算法啊,最多也就是读入输出,不过还是总结一下,反正会的也不多。那么就按照一本通的顺序好了。

  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 # define ULL unsigned long long
10 
11 using namespace std;
12 
13 const int maxn=1000006;
14 const int base=233;
15 ULL po[maxn],Hash[maxn];
16 char c[maxn];
17 int n;
18 
19 ULL div_Hash (int l,int r) //获取子串的Hashֵ值
20 {
21     return Hash[r]-Hash[l]*po[r-l+1];
22 }
23 
24 int main()
25 {
26     scanf("%s",c+1);
27     n=strlen(c+1);
28     po[0]=1;
29     for (R i=1;i<=n;++i) po[i]=po[i-1]*base;
30     for (R i=1;i<=n;++i) Hash[i]=Hash[i-1]*base+c[i];
31     return 0;
32 }
Hash-自然溢出
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 # define ULL unsigned long long
10 # define mod 1000000007
11 
12 using namespace std;
13 
14 const int maxn=1000006;
15 const int base=233;
16 ll po[maxn],Hash[maxn];
17 char c[maxn];
18 int n;
19 
20 ll div_Hash (int l,int r) //获取子串的Hashֵ值
21 {
22     return ((Hash[r]-Hash[l]*po[r-l+1])%mod+mod)%mod;
23 }
24 
25 int main()
26 {
27     scanf("%s",c+1);
28     n=strlen(c+1);
29     po[0]=1;
30     for (R i=1;i<=n;++i) po[i]=(po[i-1]*base)%mod;
31     for (R i=1;i<=n;++i) Hash[i]=(Hash[i-1]*base+c[i])%mod;
32     return 0;
33 }
Hash-模大质数
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int mod=19260817;
13 const int maxn=1000005;
14 int h,n,p1=1,ans,p2=1,a[maxn],v[maxn],firs[mod+10],nex[mod+10];
15 
16 bool que (int x)
17 {
18     int hash=x;
19     while (hash>mod) hash-=mod;
20     for (R i=firs[hash];i;i=nex[i])
21         if(v[i]==x) return true;
22     return false;
23 }
24 
25 void add (int x)
26 {
27     int hash=x;
28     while (hash>mod) hash-=mod;
29     v[++h]=x;
30     nex[h]=firs[hash];
31     firs[hash]=h;
32 }
33 
34 void del (int x)
35 {
36     int hash=x;
37     while (hash>mod) hash-=mod;
38     for (R i=firs[hash];i;i=nex[i])
39         if(v[i]==x)
40         {
41             v[i]=-1;
42             return ;
43         }
44 }
45 
46 int main()
47 {
48 
49     return 0;
50 }
哈希表
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=1000006;
13 char s[maxn],t[maxn];
14 int p[maxn],ls,lt,j;
15 
16 int main()
17 {
18     scanf("%s",s+1);
19     scanf("%s",t+1);
20     ls=strlen(s+1);
21     lt=strlen(t+1);
22     p[1]=0;
23     for (R i=2;i<=lt;++i)
24     {
25         j=p[i-1];
26         while(j&&t[i]!=t[j+1]) j=p[j];
27         if(t[i]==t[j+1]) p[i]=j+1;
28         else p[i]=0;
29     }
30     j=0;
31     for (R i=0;i<ls;++i)
32     {
33         while(j&&a[i+1]!=b[j+1]) j=p[j];
34         if(a[i+1]==b[i+1]) j++;
35         if(j==lt) ans++;
36     }
37     return 0;
38 }
kmp
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=100005*32;
13 int n,cnt,h,a[40];
14 struct Trie_01
15 {
16     int ch[maxn][2];
17     int vis[maxn];
18     void clear()
19     {
20         memset(ch,0,sizeof(ch));
21         memset(vis,0,sizeof(vis));
22     }
23     void insert()
24     {
25         int x=1;
26         for (R i=1;i<=32;++i)
27         {
28             if(!ch[x][ a[i] ])
29                 ch[ x ][ a[i] ]=++cnt;
30             x=ch[x][ a[i] ];
31         }
32         vis[x]++;
33     }
34     int find()
35     {
36         int ans=0,x=1;
37         for (R i=1;i<=32;++i)
38         {
39             if(ch[x][ a[i]^1 ])
40             {
41                 ans=ans<<1|1;
42                 x=ch[x][ a[i]^1 ];
43             }
44             else x=ch[x][ a[i] ];
45         }
46         return ans;
47     }
48 }t;
49 
50 void spilt (int x)
51 {
52     h=0;
53     while(x) a[++h]=x,x/=2;
54     for (R i=1;i<=h/2;++i) swap(a[i],a[h-i+1]);
55 }
56 
57 int main()
58 {
59 
60     return 0;
61 }
0-1Trie
  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=100005;
13 int n,cnt,len;
14 char c[maxn];
15 struct Trie_char
16 {
17     int ch[maxn][27];
18     int vis[maxn];
19     void clear()
20     {
21         memset(ch,0,sizeof(ch));
22         memset(vis,0,sizeof(vis));
23     }
24     void insert()
25     {
26         int x=1,n;
27         for (R i=1;i<=len;++i)
28         {
29             n=c[i]-'a';
30             if(!ch[x][ no ])
31                 ch[ x ][ no ]=++cnt;
32             x=ch[x][ no ];
33         }
34         vis[x]++;
35     }
36     bool find()
37     {
38         int no,x=1;
39         for (R i=1;i<=len;++i)
40         {
41             no=a[i]-'a';
42             if(!ch[x][no]) return false;
43             x=ch[x][no];
44         }
45         return vis[x];
46     }
47 }t;
48 
49 int main()
50 {
51     scanf("%s",c+1);
52     len=strlen(c+1);
53     return 0;
54 }
char-Trie

 

其它:

  
 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <string>
 5 # include <algorithm>
 6 # include <cmath>
 7 # define R register int
 8 # define ll long long
 9 
10 using namespace std;
11 
12 const int maxn=41;
13 int n,l,r;
14 ll m,a[maxn],ans,x;
15 ll lef[1<<21],rig[1<<21];
16 
17 void dfs (int x,int l,int r,int col,ll S)
18 {
19     if(x==r+1)
20     {
21         if(col==1) lef[ ++lef[0] ]=S;
22         else rig[ ++rig[0] ]=S;
23         return ;
24     }
25     dfs(x+1,l,r,col,S+a[x]);
26     dfs(x+1,l,r,col,S);
27 }
28 
29 int main()
30 {
31     scanf("%d%lld",&n,&m);
32     for (R i=1;i<=n;++i)
33         scanf("%lld",&a[i]);
34     int mid=n/2;
35     dfs(1,1,mid,1,0);
36     dfs(mid+1,mid+1,n,2,0);
37     sort(lef+1,lef+lef[0]+1);
38     sort(rig+1,rig+rig[0]+1);
39     l=-1;
40     r=rig[0];
41     for (R i=1;i<=lef[0];++i)
42     {
43         x=lef[i];
44         while(r&&x+rig[r]>m) r--;
45         if(l==-1) l=r;
46         while(l&&x+rig[l]<=m) l--;
47         ans+=(r-l);
48     }
49     printf("%lld",ans);
50     return 0;
51 }
meet in the middle
  
 1 int find_lef (int x) //x的前驱
 2 {
 3     int l=1,r=n,mid,ans=0;
 4     while(l<=r)
 5     {
 6         mid=(l+r)>>1;
 7         if(a[mid]<x)
 8             ans=max(ans,mid),l=mid+1;
 9         else
10             r=mid-1;
11     }
12     return ans;
13 }
14 
15 int find_rig (int x) //x的后继
16 {
17     int l=1,r=n,mid,ans=n;
18     while(l<=r)
19     {
20         mid=(l+r)>>1;
21         if(a[mid]>x)
22             ans=min(ans,mid),r=mid-1;
23         else
24             l=mid+1;
25     }
26     return ans;
27 }
二分法
  
 1 double open_up () //开口朝上的函数
 2 {
 3     double l=-inf,r=inf,lmid,rmid;
 4     while(r-l>=eps)
 5     {
 6         lmid=l+(l+r)/3.0;
 7         rmid=r-(l+r)/3.0;
 8         if(f(lmid)>f(rmid))
 9             l=lmid;
10         else
11             r=rmid;
12     }
13     return f(l);
14 }
15 
16 double open_down()//开口朝下的函数
17 {
18     double l=-inf,r=inf,lmid,rmid;
19     while(r-l>=eps)
20     {
21         lmid=l+(l+r)/3.0;
22         rmid=r-(l+r)/3.0;
23         if(f(lmid)<f(rmid))
24             l=lmid;
25         else
26             r=rmid;
27     }
28     return f(l);
29 }
三分

 

建议:

  1.每道题做完后可以开着$O_2$测一下,可能能查出来一些内存方面或者是局部变量忘记清零这样的错误.

  2.多组数据的题一定要记得清空数组,可以把所有定义的数组都先清空再看哪些是不必要的,定义了$STL$的队列一定要用$q.pop()$清空,千万不要用$q.front()$.所有的变量也都要清为初始状态,注意初始状态不一定是$0$!

  这里还有$asuldb$的模板库:https://35178.blog.luogu.org/noip-qian-di-ban-zi-men

  最大值赋得不够大:$memset$一个 $int$ 数组全为 $1$ 还是比 $10^9$ 小的,可以记录$-1$作为初始状态或是直接用$ll$.

  离线处理询问后忘了调回原来的顺序:记录$id$,处理完后重排序;

  奇妙的$CE$:用命令行编译可以彻底杜绝此类问题,注意编译之前另存一份,防止被编译没了.

  不要用英语单词做变量名,不要用除了$n,m,k,x,y,a,b,c,t$之外的单个字母做变量名.

  树链剖分时不要用top做变量名.

posted @ 2018-11-01 21:28  shzr  阅读(569)  评论(2编辑  收藏  举报