├── GameTheory ├── Nim积_hdu3404.cpp ├── 三种SG游戏必胜条件 └── 树博弈_pku3710.cpp ├── README ├── script ├── template.old ├── 2-sat.cpp ├── AC自动机.cpp ├── avl平衡树.cpp ├── determinant行列式.cpp ├── kmp.cpp ├── k短路(Astar算法).cpp ├── k短路偏离算法(MPS优化).cpp ├── old │ ├── heap用define.cpp │ ├── pku1276多重背包.cpp │ ├── pku2299求逆序对数.cpp │ ├── pku2513__Trie树.cpp │ ├── 前缀树.cpp │ ├── 匈牙利算法(链表).cpp │ └── 求前趋后趋.cpp ├── tire图(求改变最小的字符使得新的字符串不包含病毒串).cpp ├── trie图(求不包含某些子串的字符串个数).cpp ├── 二分图最大匹配Hopcroft_Karp.cpp ├── 伸展树.cpp ├── 利用并差集解决逻辑问题.cpp ├── 后缀数组(倍增算法).cpp ├── 图的最小环.cpp ├── 数组哈希函数.cpp ├── 最优完备匹配(slack优化KM).cpp ├── 最大流SAP(zaku).cpp ├── 最小树形图.cpp ├── 最小费用最大流(SPFA找最短增广路).cpp ├── 最短路dijkstra(heap优化).cpp ├── 最近公共祖先(k阶祖先算法).cpp ├── 最近公共祖先(lca).cpp ├── 每对点间的前k短路.cpp ├── 求凸包的上下包裹法.cpp ├── 求包含所有点的最小正方形(模拟退火算法).cpp ├── 用作hash的几个大质数.txt ├── 矩形切割.cpp ├── 矩形并的覆盖面积与轮廓周长.cpp ├── 矩阵求逆.cpp ├── 线性模方程.cpp ├── 线性素数筛选(同时利用线性素数筛选加速求积性函数).cpp ├── 统计平面上线段形成的矩形数目.cpp ├── 统计树上距离不超过k的点对数.cpp └── 计算几何.cpp ├── 图论 ├── cqf流forDitch递归形式.cpp ├── cqf流forDitch非递归形式.cpp ├── dijkstra使用优先队列.cpp ├── distanceTarjan求lca.cpp ├── exc(2-SAT问题).cpp ├── fzu2001_无向图全局最小割.cpp ├── k最短路AStar算法_pku2449.cpp ├── pku1639度限制生成树.cpp ├── pku1679_次小生成树.cpp ├── pku2186强连通分量Tarjan方法.cpp ├── pku2195_KM最大(最小)权匹配(优化版).cpp ├── pku2195_KM最大(最小)权匹配.cpp ├── pku2485用kruskal做MST.cpp ├── pku3041匈牙利算法.cpp ├── pku3487_稳定婚姻.cpp ├── zju1015_弦图判断.cpp ├── zju2314_有上下界的网络流存在性判断.cpp ├── 一般图的最大匹配.cpp ├── 二分图匹配(HK).cpp ├── 双连通分量.cpp ├── 最大团.cpp ├── 最大流SAP算法_ditch.cpp ├── 最小平均值环.cpp ├── 最小树形图pku3164.cpp ├── 最小环.cpp ├── 最小生成树prime.cpp ├── 最小费用最大流(连续最短路增广)pku3422.cpp └── 树形dp分割边求最长路.cpp ├── 备忘录 ├── 字符串 ├── AC自动机.cpp ├── Trie图_u1158.cpp ├── bob用new_lcp求最长前缀.cpp ├── hdu2222_AC自动机.cpp ├── kmp_pku3461.cpp ├── trie图_map_u1269.cpp ├── trie图(数组版).cpp ├── trie树_simple.cpp ├── zju3430_ac自动机2.cpp ├── 后缀数组_da算法.cpp └── 扩展kmp.cpp ├── 搜索 ├── dancinglink跳舞链 hust 1017.cpp └── sudoku_pku3074_dl.cpp ├── 数学 ├── 将数组hash的函数.cpp ├── 数值积分.cpp ├── 数论 │ ├── Bernoulli数.cpp │ ├── Miller_Rabin素数测试.cpp │ ├── Pollard_rho因数分解.cpp │ ├── lucas.cpp │ ├── 中国剩余定理.cpp │ ├── 中国剩余定理写成类_求x^2_mod_m=1.cpp │ ├── 中国剩余定理(不互质情况)pku2891.cpp │ ├── 原根+离散对数求高次同余底数_sgu261.cpp │ ├── 欧拉函数.cpp │ ├── 欧拉函数(求所有的).cpp │ ├── 离散对数_pku2417.cpp │ ├── 离散对数加强_pku3243.cpp │ └── 线性筛选素数与求mobius函数.cpp └── 龙贝格积分.cpp ├── 数据结构 ├── avl平衡树.cpp ├── candy求最大子矩阵.cpp ├── happy线段树_懒惰标记覆盖.cpp ├── hdu1255求矩形面积交.cpp ├── hdu1823二维线段树(更新到点).cpp ├── hdu3487_伸展树.cpp ├── hdu3563_矩形切割.cpp ├── hdu3627_动态找出右下角最靠近的点.cpp ├── mar火星地图求矩形并面积.cpp ├── pku1151_矩形切割.cpp ├── pku1177求矩形并边长.cpp ├── sbt程序forVij1081动物园o.cpp ├── spoj375_树路径剖分.cpp ├── zju3512左偏树.cpp └── 树点剖分pku1741.cpp ├── 解方程 ├── 二进制高斯消元.cpp ├── 二进制高斯消元.cpp.u1conflict ├── 环上的高斯消元_pku2947.cpp └── 高斯约旦消元.cpp ├── 计算几何 ├── convex求凸包的上下包裹法.cpp ├── 凸包相关算法.cpp └── 最近点对.cpp └── 高精度 ├── BigNumber.cpp └── fft.cpp /GameTheory/Nim积_hdu3404.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define MAX_LOG 16 //最大可能的log值,注意中间运算的结果可能会超出题目数据范围,所以这个值最好设大点 5 | #define MAX(x,y) ((x)>(y)?(x):(y)) 6 | using namespace std; 7 | int n; 8 | int f[MAX_LOG][MAX_LOG]; //记录2^x(X)2^y的值 9 | //declaration 10 | int nim_mul_normal(int x,int y); 11 | int nim_mul_power(int x,int y); 12 | // 13 | int nim_mul_power(int x,int y) //求2^x和2^y的nim积 14 | { 15 | int ret=1; 16 | if(x==0) return 1<0 || y>0;++i,x>>=1,y>>=1) 19 | { 20 | if((x&1)+(y&1)==1) 21 | ret=ret*(1<<(1<0 && u为v的后继状态 && SG[u]=0 15 | min(step[u])+1 SG[v]=0 && u为v的后继状态 16 | 先手必胜当且仅当单一游戏中最大的step为奇数。 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /GameTheory/树博弈_pku3710.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | struct EDGE{ 6 | int v,next; 7 | int opp; 8 | bool able; 9 | }e[1200]; 10 | int beg[210]; 11 | int nE; 12 | int n,m; 13 | int deep[210]; 14 | bool keyPoint[210]; 15 | void add(int x,int y) 16 | { 17 | nE++; 18 | e[nE].v=y; 19 | e[nE].able=true; 20 | e[nE].opp=nE+1; 21 | e[nE].next=beg[x]; 22 | beg[x]=nE; 23 | 24 | nE++; 25 | e[nE].v=x; 26 | e[nE].able=true; 27 | e[nE].opp=nE-1; 28 | e[nE].next=beg[y]; 29 | beg[y]=nE; 30 | } 31 | void input() 32 | { 33 | int x,y; 34 | scanf("%d%d",&n,&m); 35 | nE=0; 36 | memset(beg,0,sizeof(beg)); 37 | for(int i=0;i=0) ret^=(tm+1); 61 | else { 62 | if(keyPoint[x]) 63 | { //连接环的关键点要进行运算 64 | if(tm==-1) ret^=1; 65 | //keyPoint[x]=false; 66 | }else return tm; //环中点直接返回 67 | } 68 | } 69 | } 70 | return ret; 71 | } 72 | int main() 73 | { 74 | freopen("pku3710.in","r",stdin); 75 | int cs; 76 | int ans; 77 | while(scanf("%d",&cs)!=EOF) 78 | { 79 | ans=0; 80 | for(int t=1;t<=cs;++t) 81 | { 82 | input(); 83 | memset(deep,0,sizeof(deep)); 84 | memset(keyPoint,0,sizeof(keyPoint)); //链接环的关键点 85 | deep[1]=1; 86 | ans^=dg(1,1); 87 | } 88 | if(ans==0) printf("Harry\n"); 89 | else printf("Sally\n"); 90 | } 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 居家旅行用acm代码模板,只供参考,copyright@cypress。 2 | 3 | 4 | -------------------------------------------------------------------------------- /script: -------------------------------------------------------------------------------- 1 | /*编译*/ 2 | #!/bin/bash 3 | FILE="${GEDIT_CURRENT_DOCUMENT_NAME}" 4 | FILE_ONLY="${FILE%.*}"; 5 | 6 | g++ -ggdb -Wall -o "$FILE_ONLY" "$FILE" 7 | 8 | /*运行*/ 9 | #!/bin/bash 10 | FILE="${GEDIT_CURRENT_DOCUMENT_NAME}" 11 | FILE_ONLY="${FILE%.*}" 12 | 13 | echo -e "#!/bin/bash\nif test -e $FILE_ONLY.in;then\n./$FILE_ONLY < $FILE_ONLY.in\nelse\n./$FILE_ONLY\nfi\necho \"--end($?)--\"\nread dummy\n" >gedit.sh 14 | gnome-terminal -e "bash gedit.sh" 15 | -------------------------------------------------------------------------------- /template.old/2-sat.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/2-sat.cpp -------------------------------------------------------------------------------- /template.old/AC自动机.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/AC自动机.cpp -------------------------------------------------------------------------------- /template.old/avl平衡树.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/avl平衡树.cpp -------------------------------------------------------------------------------- /template.old/determinant行列式.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/determinant行列式.cpp -------------------------------------------------------------------------------- /template.old/kmp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define fo(i,u,d) for (long i=(u); i<=(d); ++i) 3 | using namespace std; 4 | 5 | const long maxn=10000; 6 | 7 | char s[maxn],ss[maxn]; 8 | long next[maxn],len; 9 | 10 | void make_next() 11 | { 12 | long j; 13 | next[0]=-1; 14 | len=strlen(s); 15 | fo(i,1,len) { 16 | for (j=next[i-1]; j>=0 && s[j]!=s[i-1]; j=next[j]); 17 | next[i]=j+1; 18 | } 19 | } 20 | void solve() 21 | { 22 | 23 | while (scanf("%s",ss)!=EOF) { 24 | long j=0, ans=0; 25 | fo(i,1,len) { 26 | while (j>=0 && s[i-1]!=ss[j]) j=next[j]; 27 | ++j; 28 | ans=ans 2 | #include 3 | using namespace std; 4 | bool f[100000]; 5 | int cash,n; 6 | int num[11]; 7 | int w[11]; 8 | int main() 9 | { 10 | freopen("test.in","r",stdin); 11 | while (scanf("%d",&cash)!=EOF) 12 | { 13 | scanf("%d",&n); 14 | for(int i=1;i<=n;++i) 15 | scanf("%d%d",&num[i],&w[i]); 16 | memset(f,0,sizeof(f)); 17 | f[0]=1; 18 | for(int i=1;i<=n;++i) 19 | { 20 | int k=1; 21 | while(k<=num[i]) 22 | { 23 | for(int j=cash;j>=k*w[i];--j) 24 | f[j]|=f[j-k*w[i]]; 25 | num[i]-=k; 26 | k<<=1; 27 | } 28 | k=num[i]; 29 | for(int j=cash;j>=k*w[i];--j) 30 | f[j]|=f[j-k*w[i]]; 31 | } 32 | for(int i=cash;i>=0;--i) 33 | if(f[i]) 34 | { 35 | printf("%d\n",i); 36 | break; 37 | } 38 | } 39 | return 0; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /template.old/old/pku2299求逆序对数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | int n; 5 | int a[500010],tmp[500010]; 6 | long long ans; 7 | void mergsort(int l,int r) 8 | { 9 | if(lc1||a1[l1]>a2[l2])&&(l2<=c2)) 20 | { 21 | a3[++l3]=a2[l2++]; 22 | ans+=c1-l1+1; 23 | } 24 | else if((l2>c2||a1[l1]c1) a3[++l3]=a2[l2++]; 29 | else a3[++l3]=a1[l1++]; 30 | } 31 | } 32 | for(int i=l;i<=r;++i) 33 | a[i]=tmp[i]; 34 | } 35 | } 36 | int main() 37 | { 38 | freopen("test.in","r",stdin); 39 | scanf("%d",&n); 40 | int x; 41 | while(n!=0) 42 | { 43 | for(int i=1;i<=n;++i) 44 | scanf("%d",&a[i]); 45 | ans=0; 46 | mergsort(1,n); 47 | printf("%lld\n",ans); 48 | scanf("%d",&n); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /template.old/old/pku2513__Trie树.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/old/pku2513__Trie树.cpp -------------------------------------------------------------------------------- /template.old/old/前缀树.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/old/前缀树.cpp -------------------------------------------------------------------------------- /template.old/old/匈牙利算法(链表).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define N 10010 5 | #define M 1000000 6 | using namespace std; 7 | 8 | struct EDGE 9 | { 10 | int v,next; 11 | }e[M]; 12 | 13 | int en,turn; 14 | int pt[N]; 15 | int mark[N]; 16 | int beg[N],n; 17 | 18 | void add(int x,int y) 19 | { 20 | en++; 21 | e[en].v=y; 22 | e[en].next=beg[x]; 23 | beg[x]=en; 24 | } 25 | void input() 26 | { 27 | int num,x,y; 28 | 29 | en=0; 30 | memset(beg,0,sizeof(beg)); 31 | for(int l=1;l<=n;++l) 32 | { 33 | scanf("%d",&x); 34 | x++; 35 | while(getchar()!=':') ; 36 | while(getchar()!='(') ; 37 | scanf("%d",&num); 38 | while(getchar()!=')') ; 39 | for(int i=1;i<=num;++i) 40 | { 41 | scanf("%d",&y); 42 | y++; 43 | y-=n; 44 | add(x,y); 45 | } 46 | } 47 | } 48 | bool dfs(int x) 49 | { 50 | for(int i=beg[x];i;i=e[i].next) 51 | { 52 | int v=e[i].v; 53 | if(mark[v]==turn) continue; 54 | mark[v]=turn; 55 | if(pt[v]==-1 || dfs(pt[v])) 56 | { 57 | pt[v]=x; 58 | return true; 59 | } 60 | } 61 | return false; 62 | } 63 | void solve() 64 | { 65 | int ans=0; 66 | memset(mark,0,sizeof(mark)); 67 | memset(pt,0xff,sizeof(pt)); 68 | for(turn=1;turn<=n;++turn) 69 | if (dfs(turn)) ans++; 70 | printf("%d\n",ans); 71 | } 72 | int main() 73 | { 74 | freopen("c.in","r",stdin); 75 | while(scanf("%d",&n)!=EOF) 76 | { 77 | input(); 78 | solve(); 79 | } 80 | return 0; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /template.old/old/求前趋后趋.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/old/求前趋后趋.cpp -------------------------------------------------------------------------------- /template.old/tire图(求改变最小的字符使得新的字符串不包含病毒串).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/tire图(求改变最小的字符使得新的字符串不包含病毒串).cpp -------------------------------------------------------------------------------- /template.old/trie图(求不包含某些子串的字符串个数).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/trie图(求不包含某些子串的字符串个数).cpp -------------------------------------------------------------------------------- /template.old/二分图最大匹配Hopcroft_Karp.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/二分图最大匹配Hopcroft_Karp.cpp -------------------------------------------------------------------------------- /template.old/伸展树.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/伸展树.cpp -------------------------------------------------------------------------------- /template.old/利用并差集解决逻辑问题.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/利用并差集解决逻辑问题.cpp -------------------------------------------------------------------------------- /template.old/后缀数组(倍增算法).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/后缀数组(倍增算法).cpp -------------------------------------------------------------------------------- /template.old/图的最小环.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/图的最小环.cpp -------------------------------------------------------------------------------- /template.old/数组哈希函数.cpp: -------------------------------------------------------------------------------- 1 | inline int hashcode(const int *v) 2 | { 3 | int s = 0; 4 | for(int i=0; i>4))^(v[i]<<10); 6 | s = s % M; 7 | s = s < 0 ? s + M : s; 8 | return s; 9 | } 10 | -------------------------------------------------------------------------------- /template.old/最优完备匹配(slack优化KM).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/最优完备匹配(slack优化KM).cpp -------------------------------------------------------------------------------- /template.old/最大流SAP(zaku).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/最大流SAP(zaku).cpp -------------------------------------------------------------------------------- /template.old/最小树形图.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/最小树形图.cpp -------------------------------------------------------------------------------- /template.old/最小费用最大流(SPFA找最短增广路).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/最小费用最大流(SPFA找最短增广路).cpp -------------------------------------------------------------------------------- /template.old/最短路dijkstra(heap优化).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/最短路dijkstra(heap优化).cpp -------------------------------------------------------------------------------- /template.old/最近公共祖先(k阶祖先算法).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/最近公共祖先(k阶祖先算法).cpp -------------------------------------------------------------------------------- /template.old/最近公共祖先(lca).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/最近公共祖先(lca).cpp -------------------------------------------------------------------------------- /template.old/每对点间的前k短路.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/每对点间的前k短路.cpp -------------------------------------------------------------------------------- /template.old/求凸包的上下包裹法.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/求凸包的上下包裹法.cpp -------------------------------------------------------------------------------- /template.old/求包含所有点的最小正方形(模拟退火算法).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/求包含所有点的最小正方形(模拟退火算法).cpp -------------------------------------------------------------------------------- /template.old/用作hash的几个大质数.txt: -------------------------------------------------------------------------------- 1 | 9973,8377,7591,7879,8583,8609,9199,9257,9613 2 | 101,119993 3 | -------------------------------------------------------------------------------- /template.old/矩形切割.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/矩形切割.cpp -------------------------------------------------------------------------------- /template.old/矩形并的覆盖面积与轮廓周长.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/矩形并的覆盖面积与轮廓周长.cpp -------------------------------------------------------------------------------- /template.old/矩阵求逆.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/矩阵求逆.cpp -------------------------------------------------------------------------------- /template.old/线性模方程.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/线性模方程.cpp -------------------------------------------------------------------------------- /template.old/线性素数筛选(同时利用线性素数筛选加速求积性函数).cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/线性素数筛选(同时利用线性素数筛选加速求积性函数).cpp -------------------------------------------------------------------------------- /template.old/统计平面上线段形成的矩形数目.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/统计平面上线段形成的矩形数目.cpp -------------------------------------------------------------------------------- /template.old/统计树上距离不超过k的点对数.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/统计树上距离不超过k的点对数.cpp -------------------------------------------------------------------------------- /template.old/计算几何.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/template.old/计算几何.cpp -------------------------------------------------------------------------------- /图论/cqf流forDitch递归形式.cpp: -------------------------------------------------------------------------------- 1 | //cqf_flow_demo_for_ditch 2 | #include 3 | #include 4 | #define MAXN 60005 5 | #define MAXM 1000001 6 | #define MAXNUM 2000000000 7 | using namespace std; 8 | struct node 9 | { int v,c,f,next;}org_node[2*MAXM+1]; 10 | int n,m,num=0,s,t,remain=0,xp; 11 | int unq[MAXN]; 12 | node *edge=&org_node[MAXM]; 13 | int beg[MAXN],rec[MAXN],next[MAXN]; 14 | int a[MAXM],b[MAXM],c[MAXM]; 15 | void init() 16 | { 17 | scanf("%d%d",&m,&n); 18 | for (int i=0;i 6 | #include 7 | #define MAXN 510 8 | #define inf 1000000000 9 | using namespace std; 10 | int w[MAXN]; 11 | int link[MAXN][MAXN]; 12 | bool inq[MAXN]; 13 | bool die[MAXN]; //die表示i是否已经被合并了 14 | int n,m,left; 15 | void input() 16 | { 17 | int x,y,c; 18 | memset(link,0,sizeof(link)); 19 | for(int i=0;i=0 && s=0 && tMax) Max=w[j],x=j; //每次选择一个不在A中的而且与A的link和最大的那个点加入到A中 49 | inq[x]=true; 50 | if(x==-1) return 0; 51 | s=t; t=x; //记录加入顺序的最后两个 52 | for(int j=0;j 2 | #include 3 | #include 4 | #include 5 | #define N 1010 6 | #define M 100010 7 | #define INF 1000000000 8 | using namespace std; 9 | struct EDGE{ 10 | int v,next,len; 11 | }e1[M],e2[M]; 12 | struct NODE{ 13 | int v,len; 14 | NODE(int _v=0,int _len=0):v(_v),len(_len){} 15 | bool operator<(const NODE &that)const{ 16 | return len>that.len; 17 | } 18 | }; 19 | priority_queue que; 20 | 21 | int beg1[N],beg2[N],nE1,nE2; 22 | int h[N]; //每个点到t的距离 23 | int cnt[N]; 24 | bool mark[N]; 25 | int n,m,k; 26 | int s,t; 27 | void add(int x,int y,int l) 28 | { 29 | nE1++; 30 | e1[nE1].v=y; e1[nE1].next=beg1[x]; e1[nE1].len=l; beg1[x]=nE1; 31 | nE2++; 32 | e2[nE2].v=x; e2[nE2].next=beg2[y]; e2[nE2].len=l; beg2[y]=nE2; 33 | } 34 | void input() 35 | { 36 | int x,y,l; 37 | memset(beg1,0,sizeof(beg1)); 38 | memset(beg2,0,sizeof(beg2)); 39 | nE1=nE2=0; 40 | for(int i=0;ik) continue; 89 | for(int i=beg1[u];i;i=e1[i].next) 90 | { 91 | v=e1[i].v; 92 | que.push(NODE(v,len-h[u]+h[v]+e1[i].len)); //len-h[u]为s到u的标号距离 93 | } 94 | } 95 | return -1; 96 | } 97 | int main() 98 | { 99 | freopen("pku2449.in","r",stdin); 100 | while(scanf("%d%d",&n,&m)!=EOF) 101 | { 102 | input(); 103 | dij(); 104 | printf("%d\n",astar()); 105 | } 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /图论/pku1639度限制生成树.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/图论/pku1639度限制生成树.cpp -------------------------------------------------------------------------------- /图论/pku1679_次小生成树.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 1.先求原图的最小生成树T,并记录树边和最小值small1 3 | 2.然后求dis[i][j],表示在T中x到y的唯一路径上的最大边 4 | 3.枚举所有非树边(u,v),设其值为w,那么small2=min{small1-dis[u][v]+w},最后看small1和 5 | small2是否一样就可以了。 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define maxn 110 13 | #define maxm 10000 14 | using namespace std; 15 | struct edge{ 16 | int u,v,w,next,inv; 17 | bool inTree; 18 | }; 19 | vector e; 20 | int id[maxm]; 21 | int beg[maxn]; 22 | int fa[maxn]; 23 | int dis[maxn][maxn]; 24 | int n,m; 25 | int small1,small2; 26 | int nE; 27 | void add(int x,int y ,int z,int invFlag) 28 | { 29 | e.push_back(edge()); 30 | int last=e.size()-1; 31 | e[last].u=x; 32 | e[last].v=y; 33 | e[last].next=beg[x]; 34 | e[last].w=z; 35 | e[last].inTree=false; 36 | beg[x]=last; 37 | 38 | if(!invFlag) e[last].inv=last+1; 39 | else e[last].inv=last-1; 40 | } 41 | bool cmp(int x,int y) 42 | { 43 | return e[x].wnow) dfs(e[i].v,x,e[i].w,best); 100 | else dfs(e[i].v,x,now,best); 101 | } 102 | } 103 | void find_dis() 104 | { 105 | memset(dis,0,sizeof(dis)); 106 | for(int i=1;i<=n;++i) 107 | dfs(i,0,0,dis[i]); 108 | } 109 | void cal_second() 110 | { 111 | small2=2000000000; 112 | for(int i=1;i<=nE;++i) 113 | if(!e[i].inTree){ 114 | int sub=dis[e[i].u][e[i].v]; 115 | if(small1-sub+e[i].w 2 | #include 3 | #define maxn 510 4 | #define inf 1000000000 5 | using namespace std; 6 | 7 | int lk[maxn]; 8 | int lx[maxn],ly[maxn]; 9 | bool sx[maxn],sy[maxn]; 10 | int w[maxn][maxn]; 11 | bool link[maxn][maxn]; 12 | int slack[maxn]; 13 | int n,m,nx,ny,e; 14 | int cs; 15 | void input() 16 | { 17 | int s,r,v; 18 | memset(w,0,sizeof(w)); 19 | memset(link,0,sizeof(link)); //link 表示是否连通 20 | for(int i=0;ilx[i]) lx[i]=w[i][j]; 57 | } 58 | for(int i=1;i<=nx;++i) 59 | { 60 | for(int j=1;j<=ny;j++) slack[j]=inf; 61 | for(int l=1;l<=nx;l++) //最多增加nx条边 62 | { 63 | memset(sx,0,sizeof(sx)); 64 | memset(sy,0,sizeof(sy)); 65 | if(dfs(i)) break; 66 | int d=inf; 67 | for(int j=1;j<=ny;++j) 68 | if(!sy[j] && slack[j]0) { 95 | KM(); 96 | output(); 97 | }else printf("-1\n"); 98 | } 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /图论/pku2195_KM最大(最小)权匹配.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/图论/pku2195_KM最大(最小)权匹配.cpp -------------------------------------------------------------------------------- /图论/pku2485用kruskal做MST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define MAX 1000000000 5 | using namespace std; 6 | struct edge 7 | { 8 | int u,v,w; 9 | }; 10 | edge e[250010]; 11 | int fa[510]; 12 | int m,n; 13 | bool cmp(const edge &p1,const edge &p2) 14 | { 15 | return p1.wans) ans=e[i].w; 44 | fa[x]=y; 45 | } 46 | } 47 | printf("%d\n",ans); 48 | } 49 | int main() 50 | { 51 | freopen("test.in","r",stdin); 52 | int cs,tm; 53 | scanf("%d",&cs); 54 | while(cs--) 55 | { 56 | scanf("%d",&n); 57 | m=0; 58 | for(int i=1;i<=n;++i) 59 | for(int j=1;j<=n;++j) 60 | { 61 | scanf("%d",&tm); 62 | e[++m].u=i;e[m].v=j;e[m].w=tm; 63 | e[++m].u=j;e[m].v=i;e[m].w=tm; 64 | } 65 | kru(); 66 | } 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /图论/pku3041匈牙利算法.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | bool g[510][510]; 5 | int mark[510]; 6 | int p[510]; 7 | int n,k,turn; 8 | int ans; 9 | bool dfs(int src) 10 | { 11 | for(int i=1;i<=n;++i) 12 | if (g[src][i]&&mark[i]!=turn) 13 | { 14 | mark[i]=turn; 15 | if (p[i]==-1||dfs(p[i])) 16 | { 17 | p[i]=src; 18 | return true; 19 | } 20 | } 21 | return false; 22 | } 23 | int main() 24 | { 25 | freopen("test.in","r",stdin); 26 | int x,y; 27 | while (scanf("%d%d",&n,&k)!=EOF) 28 | { 29 | memset(g,0,sizeof(g)); 30 | memset(p,0xff,sizeof(p)); 31 | for(int i=1;i<=k;++i) 32 | { 33 | scanf("%d%d",&x,&y); 34 | g[x][y]=1; 35 | } 36 | turn=0; 37 | ans=0; 38 | for(int i=1;i<=n;++i) 39 | { 40 | ++turn; 41 | if(dfs(i)) ++ans; 42 | } 43 | printf("%d\n",ans); 44 | } 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /图论/pku3487_稳定婚姻.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define maxn 30 4 | //male-optimal,谁求婚则谁优先 5 | using namespace std; 6 | int ra[maxn][maxn],rb[maxn][maxn]; //ra[i][j] i对j的排名,1最高 7 | int ach[maxn],bch[maxn]; //a,b的选择配偶 8 | int list[maxn][maxn]; //b的求婚队列 9 | bool deny[maxn][maxn]; //deny[i][j]表示i是否拒绝过j 10 | int n,cs; 11 | void input() 12 | { 13 | char str[40]; 14 | scanf("%d",&n); 15 | for(int i=1;i<=2*n;i++) 16 | scanf("%s",str); 17 | memset(ra,0,sizeof(ra)); 18 | memset(rb,0,sizeof(rb)); 19 | for(int i=1;i<=n;i++) 20 | { 21 | scanf("%s",str); 22 | //printf("%s\n",str); 23 | int u=str[0]-'a'+1; 24 | for(int j=2;str[j];j++) 25 | ra[u][str[j]-'A'+1]=j-1; 26 | } 27 | for(int i=1;i<=n;i++) 28 | { 29 | scanf("%s",str); 30 | int u=str[0]-'A'+1; 31 | for(int j=2;str[j];j++) 32 | rb[u][str[j]-'a'+1]=j-1; 33 | } 34 | } 35 | void stable_marriage() 36 | { 37 | memset(ach,0,sizeof(ach)); 38 | memset(bch,0,sizeof(bch)); 39 | memset(deny,0,sizeof(deny)); 40 | bool all_married; 41 | do{ 42 | all_married=true; 43 | for(int i=1;i<=n;i++) list[i][0]=0; 44 | //for male 45 | for(int i=1;i<=n;i++) //每轮所有男士对尚未拒绝他的女士中选出最喜欢的求婚 46 | if(!ach[i]){ 47 | all_married=false; 48 | int rank=n+1,who=-1; 49 | for(int j=1;j<=n;j++) 50 | if(!deny[j][i] && ra[i][j] 12 | #include 13 | #define maxn 1010 14 | using namespace std; 15 | int n,m; 16 | bool go[maxn][maxn],vis[maxn]; 17 | int lab[maxn],seq[maxn]; 18 | int tmp[maxn]; 19 | void input() 20 | { 21 | int x,y; 22 | memset(go,0,sizeof(go)); 23 | for(int i=0;i=0;i--) 35 | { 36 | int x=-1; 37 | for(int j=0;jlab[x] )) x=j; 39 | seq[i]=x; 40 | vis[x]=true; 41 | for(int j=0;j ∑g(i, v) - ∑g(u, i) = ∑B(u, i) - ∑B(i, v)。如果设M(i) = ∑B(u, i) - ∑B(i, v),即M(i)为流入结点i的下界总和减去流出i的下界总和。 3 |   至此,可如此构造一个只有流量上界的附加网络:增加附加源S'和附加汇T',原网络中M(i)非负,则C'(S', i) = M(i),否则C'(i, T') = -M(i);原网络中任意有弧相连的结点u和结点v在附加网络中的弧C'(u, v) = C(u, v) - B(u, v)。 4 | 5 |   这样,如果附加网络满流,则在原网络中就存在一个与之对应的可行流。而想判断附加网络能否满流可通过求解附加网络的最大流进行判断。如果满流,则有解;否则无解。 6 | 7 |   这个问题弄明白后,就可以进行下一步的求解有上下界网络中的最大流和最小流问题了。 8 | 9 |   增加一条弧(T, S),使原网络变成一个无源汇的网络。如果求最大流,则B(T, S) = a,C(T, S) = inf;如果求解最小流,则B(T, S) = 0,C(T, S) = a。可以通过二分法枚举a,按上文提到的方法构造附加网络,判断附加网络中是否有可行流即可。最终,a即为所求。 10 | 11 |   这种方法实现起来较为简单,所需的代价是多次求解最大流。复杂度为O(logF Maxflow(V, E))。 12 | */ 13 | #include 14 | #include 15 | #include 16 | #define maxn 1010 17 | #define inf 1000000000 18 | using namespace std; 19 | 20 | struct edge{ 21 | int v,c,next; 22 | int base; 23 | int rc; 24 | }; 25 | vector e; 26 | int beg[maxn]; 27 | // 28 | int last[maxn]; 29 | int M[maxn]; 30 | int full; 31 | int d[maxn],cnt_d[maxn]; 32 | // 33 | int n,m,st,ed; 34 | void add(int x,int y,int c,int base=0) 35 | { 36 | int nE=e.size(); 37 | e.push_back(edge()); 38 | e[nE].v=y; 39 | e[nE].c=e[nE].rc=c; 40 | e[nE].base=base; 41 | e[nE].next=beg[x]; 42 | beg[x]=nE; 43 | } 44 | void input() 45 | { 46 | int x,y,low,high; 47 | e.resize(0); 48 | memset(beg,255,sizeof(beg)); 49 | memset(M,0,sizeof(M)); 50 | scanf("%d%d",&n,&m); 51 | st=0;ed=n+1; 52 | for(int i=1;i<=m;++i) 53 | { 54 | scanf("%d%d%d%d",&x,&y,&low,&high); 55 | M[x]-=low; 56 | M[y]+=low; 57 | add(x,y,high-low,low); 58 | add(y,x,0); 59 | } 60 | full=0; 61 | for(int i=1;i<=n;++i) 62 | if(M[i]>0) add(st,i,M[i]),add(i,st,0),full+=M[i]; 63 | else if(M[i]<0) add(i,ed,-M[i]),add(ed,i,0); 64 | n++; 65 | for(int i=0;i<=n;++i) last[i]=beg[i]; 66 | } 67 | int Min(int x,int y) 68 | { 69 | return xn) return 0; 88 | } 89 | minD=Min(minD,d[e[i].v]); 90 | } 91 | i=e[i].next==-1?beg[x]:e[i].next; 92 | }while(i!=last[x]); 93 | if(--cnt_d[d[x]]==0) d[st]=n+1; 94 | d[x]=minD+1; 95 | cnt_d[d[x]]++; 96 | return 0; 97 | } 98 | void max_flow() 99 | { 100 | int ans=0; 101 | memset(d,0,sizeof(d)); 102 | memset(cnt_d,0,sizeof(cnt_d)); 103 | while(d[st]<=n) 104 | ans+=sap(st,inf); 105 | if(ans==full){ 106 | printf("YES\n"); 107 | for(int i=0;i<2*m;i+=2) 108 | printf("%d\n",e[i].rc-e[i].c+e[i].base); 109 | printf("\n"); 110 | }else printf("NO\n\n"); 111 | } 112 | int main() 113 | { 114 | freopen("zju2314.in","r",stdin); 115 | int cs; 116 | scanf("%d",&cs); 117 | while(cs--) 118 | { 119 | input(); 120 | max_flow(); 121 | } 122 | return 0; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /图论/一般图的最大匹配.cpp: -------------------------------------------------------------------------------- 1 | //author: momodi@whuacm 2 | struct Graph { 3 | int n, match[maxn]; 4 | bool adj[maxn][maxn]; 5 | void clear() { 6 | memset(adj, 0, sizeof(adj)); 7 | n = 0; 8 | } 9 | void insert(const int &u, const int &v) { 10 | get_max(n, max(u, v) + 1); 11 | adj[u][v] = adj[v][u] = 1; 12 | } 13 | int max_match() { 14 | memset(match, -1, sizeof(match)); 15 | int ans = 0; 16 | for (int i = 0; i < n; ++i) { 17 | if (match[i] == -1) { 18 | ans += bfs(i); 19 | } 20 | } 21 | return ans; 22 | } 23 | int Q[maxn], pre[maxn], base[maxn]; 24 | bool hash[maxn]; 25 | bool in_blossom[maxn]; 26 | int bfs(int p) { 27 | memset(pre, -1, sizeof(pre)); 28 | memset(hash, 0, sizeof(hash)); 29 | for (int i = 0; i < n; ++i) { 30 | base[i] = i; 31 | } 32 | Q[0] = p; 33 | hash[p] = 1; 34 | for (int s = 0, t = 1; s < t; ++s) { 35 | int u = Q[s]; 36 | for (int v = 0; v < n; ++v) { 37 | if (adj[u][v] && base[u] != base[v] && v != match[u]) { 38 | if (v == p || (match[v] != -1 && pre[match[v]] != -1)) { 39 | int b = contract(u, v); 40 | for (int i = 0; i < n; ++i) { 41 | if (in_blossom[base[i]]) { 42 | base[i] = b; 43 | if (hash[i] == 0) { 44 | hash[i] = 1; 45 | Q[t++] = i; 46 | } 47 | } 48 | } 49 | } else if (pre[v] == -1) { 50 | pre[v] = u; 51 | if (match[v] == -1) { 52 | argument(v); 53 | return 1; 54 | } else { 55 | Q[t++] = match[v]; 56 | hash[match[v]] = 1; 57 | } 58 | } 59 | } 60 | } 61 | } 62 | return 0; 63 | } 64 | void argument(int u) { 65 | while (u != -1) { 66 | int v = pre[u]; 67 | int k = match[v]; 68 | match[u] = v; 69 | match[v] = u; 70 | u = k; 71 | } 72 | } 73 | void change_blossom(int b, int u) { 74 | while (base[u] != b) { 75 | int v = match[u]; 76 | in_blossom[base[v]] = in_blossom[base[u]] = true; 77 | u = pre[v]; 78 | if (base[u] != b) { 79 | pre[u] = v; 80 | } 81 | } 82 | } 83 | int contract(int u, int v) { 84 | memset(in_blossom, 0, sizeof(in_blossom)); 85 | int b = find_base(base[u], base[v]); 86 | change_blossom(b, u); 87 | change_blossom(b, v); 88 | if (base[u] != b) { 89 | pre[u] = v; 90 | } 91 | if (base[v] != b) { 92 | pre[v] = u; 93 | } 94 | return b; 95 | } 96 | int find_base(int u, int v) { 97 | bool in_path[maxn] = {}; 98 | while (true) { 99 | in_path[u] = true; 100 | if (match[u] == -1) { 101 | break; 102 | } 103 | u = base[pre[match[u]]]; 104 | } 105 | while (!in_path[v]) { 106 | v = base[pre[match[v]]]; 107 | } 108 | return v; 109 | } 110 | }; 111 | -------------------------------------------------------------------------------- /图论/二分图匹配(HK).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define N 10010 4 | #define M 1000010 5 | #define INF 2000000000 6 | using namespace std; 7 | struct EDGE 8 | { 9 | int v,next; 10 | }; 11 | EDGE e[M]; 12 | int n,en; 13 | int beg[N]; 14 | int lx[N],ly[N]; 15 | int que[N]; 16 | int dx[N],dy[N]; 17 | void add(int x,int y) 18 | { 19 | en++; 20 | e[en].v=y; 21 | e[en].next=beg[x]; 22 | beg[x]=en; 23 | } 24 | void input() 25 | { 26 | int num,x,y; 27 | en=0; 28 | memset(beg,0,sizeof(beg)); 29 | for(int l=1;l<=n;++l) 30 | { 31 | scanf("%d",&x); 32 | x++; 33 | while(getchar()!=':'); 34 | while(getchar()!='('); 35 | scanf("%d",&num); 36 | while(getchar()!=')'); 37 | for(int i=1;i<=num;++i) 38 | { 39 | scanf("%d",&y); 40 | y++; 41 | y-=n; 42 | add(x,y); 43 | } 44 | } 45 | } 46 | bool bfs() 47 | { 48 | int st=1,ed=0; 49 | bool flag=false; 50 | memset(dx,0,sizeof(dx)); 51 | memset(dy,0,sizeof(dy)); 52 | for(int i=1;i<=n;++i) 53 | if(!lx[i]) que[++ed]=i; 54 | for(;st<=ed;++st) 55 | { 56 | int cur=que[st]; 57 | for(int i=beg[cur];i;i=e[i].next) 58 | { 59 | int v=e[i].v; 60 | if(!dy[v]) 61 | { 62 | dy[v]=dx[cur]+1; 63 | if(!ly[v]) flag=true; 64 | else dx[ly[v]]=dy[v]+1,que[++ed]=ly[v]; 65 | } 66 | } 67 | } 68 | return flag; 69 | } 70 | bool dfs(int x) 71 | { 72 | for(int i=beg[x];i;i=e[i].next) 73 | { 74 | int y=e[i].v; 75 | if(dy[y]==dx[x]+1) 76 | { 77 | dy[y]=0; 78 | if(!ly[y] || dfs(ly[y])) 79 | { 80 | ly[y]=x; 81 | lx[x]=y; 82 | return true; 83 | } 84 | } 85 | } 86 | return false; 87 | } 88 | void solve() 89 | { 90 | memset(lx,0,sizeof(lx)); 91 | memset(ly,0,sizeof(ly)); 92 | int ans=0; 93 | while(bfs()) 94 | { 95 | for(int i=1;i<=n;++i) 96 | if(!lx[i] && dfs(i)) ++ans; 97 | } 98 | printf("%d\n",ans); 99 | } 100 | int main() 101 | { 102 | freopen("C.IN","r",stdin); 103 | while(scanf("%d",&n)!=EOF) 104 | { 105 | input(); 106 | solve(); 107 | } 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /图论/双连通分量.cpp: -------------------------------------------------------------------------------- 1 | 双连通分量: 2 | 3 | 双连通分量分两种,一种是删除一条边仍然连通的,叫做边连通分量,以桥为分割,另外一个是删除一个点仍然连通,以割点为分界叫点连通分量,下面分开来讲。 4 | 5 | 6 | 边连通分量: 7 | 其实把所有的桥都找出来就可以进行划分了。这是对点的划分。 8 | void dfs(int x,int fat) 9 | { 10 | low[x]=dfn[x]=++len; 11 | for(int q=beg[x];q!=-1;q=e[q].next) 12 | if(e[q].v!=fat) 13 | { 14 | int v=e[q].v; 15 | if(dfn[v]==0) 16 | { 17 | dfs(v,x); 18 | if(low[v]=dfn[x]) key[x]=true; //x 为割点 20 | if(low[v]>dfn[x]) bridge[x][v]=true; // x-v 为桥 21 | } else if(dfn[v]=pre[x]){ //we get a cut point 41 | bcc++; 42 | BCC[bcc].resize(0); 43 | int w; 44 | //注意这里的退栈操作,要退到v,不能一直退到x, 45 | //因为有可能x先访问另外一个儿子u,然后u能连到比x更早的祖先,那么u和u连接的一些 46 | //节点就仍然在栈中,这时候对v进行访问,如果此时一直退栈到x,那么就会把u也给退栈,就会造成错误 47 | do{ 48 | w=stk[top--]; 49 | BCC[bcc].push_back(w); 50 | inBcc[bcc][w]=true; //true表示w在编号为bcc的点连通分量中 51 | }while(w!=v); 52 | BCC[bcc].push_back(x); //最后记得把当前割点也加到bcc的分量中。 53 | inBcc[bcc][x]=true; 54 | } 55 | if(low[v] 2 | #include 3 | #include 4 | using namespace std; 5 | struct MaxClique //base from 0 6 | { 7 | static const int MAXN=51; 8 | int n,ne,max; 9 | int best[MAXN],rec[MAXN]; 10 | bool link[MAXN][MAXN]; 11 | 12 | MaxClique(int _n) 13 | { 14 | n=_n; 15 | clear(); 16 | } 17 | void setn(int _n){ n=_n; } 18 | void clear() 19 | { 20 | memset(link,0,sizeof(link)); 21 | } 22 | void insert(int u,int v) 23 | { 24 | link[u][v]=link[v][u]=true; 25 | } 26 | bool dfs(int n,int u[],int size,int ret[]) 27 | { 28 | if(n) 29 | { 30 | if(size+best[u[0]]<=max) return false; 31 | int v[MAXN],vn,i,j; 32 | for(i=0;imax){ 40 | max=size; 41 | for(int i=0;i=0;i--) 52 | { 53 | for(vn=0,j=i+1;j 2 | #include 3 | #include 4 | #define maxn 1010 5 | #define inf 1000000000 6 | using namespace std; 7 | 8 | struct edge{ 9 | int v,c,next; 10 | }; 11 | vector e; 12 | int beg[maxn]; 13 | // 14 | int last[maxn]; 15 | int d[maxn],cnt_d[maxn]; 16 | // 17 | int n,m,st,ed,tot; 18 | void add(int x,int y,int c) 19 | { 20 | int nE=e.size(); 21 | e.push_back(edge()); 22 | e[nE].v=y; 23 | e[nE].c=c; 24 | e[nE].next=beg[x]; 25 | beg[x] = nE; 26 | } 27 | void input() 28 | { 29 | int x,y,c; 30 | e.resize(0); 31 | memset(beg,255,sizeof(beg)); 32 | for(int i=1;i<=m;++i) 33 | { 34 | scanf("%d%d%d",&x,&y,&c); 35 | add(x,y,c); 36 | add(y,x,0); 37 | } 38 | st=1; ed=n; 39 | 40 | tot=n+1; //tot赋初始值 41 | for(int i=0;i<=tot;i++) last[i]=beg[i]; //注意last 要给初始值,而且不能放在add中,否则当无边时会出错。 42 | } 43 | int Min(int x,int y) 44 | { 45 | return xtot) return 0; 64 | } 65 | minD=Min(minD,d[e[i].v]); 66 | } 67 | i=e[i].next==-1?beg[x]:e[i].next; 68 | }while(i!=last[x]); 69 | if(--cnt_d[d[x]]==0) d[st]=tot+1; 70 | d[x]=minD+1; 71 | cnt_d[d[x]]++; 72 | return 0; 73 | } 74 | void max_flow() 75 | { 76 | int ans=0; 77 | memset(d,0,sizeof(d)); 78 | memset(cnt_d,0,sizeof(cnt_d)); 79 | while(d[st]<=tot) //tot 表示流量图的最大点数 80 | ans+=sap(st,inf); 81 | printf("%d\n",ans); 82 | } 83 | int main() 84 | { 85 | while(scanf("%d%d",&m,&n)!=EOF) 86 | { 87 | input(); 88 | max_flow(); 89 | } 90 | return 0; 91 | } 92 | 93 | -------------------------------------------------------------------------------- /图论/最小平均值环.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 一張圖上每條邊都有權重,最小平均值環是「權重除以邊數」最小的環,可能有許多只。 3 | 最小平均值環也可以視作是最小比率環的特例,當每條邊的第二組權重都等於 1 的時候。 4 | 5 | 令V為圖上的所有點構成的集合,n為圖上的點數。 6 | 圖上任意取一個點作為起點,d(k, i)為起點走k條邊到達i的最短路徑。 7 | d(n, i) - d(k, i) 8 | 平均權重 = min max ───────────────── 9 | i∊V 0≤k≤n-1 n - k 10 | 如果圖上有不連通的部分,可以使用最短路徑 Johnson's Algorithm 所提到的技巧,在圖上另外新增一個起點,並且增加起點連到圖上其他點的邊,其權重皆設為零。如此一來,圖上的每一個點都可以由起點走到,而且最小平均值環也不會改變。 11 | 12 | uva 11090 13 | */ 14 | #include 15 | #include 16 | #define maxm 2600 17 | #define maxn 55 18 | #define inf 1000000000 19 | typedef long long ll; 20 | using namespace std; 21 | 22 | struct edge{ 23 | int u,v,c,next; 24 | }e[maxm]; 25 | int beg[maxn]; 26 | int n,cs,ne,st,m; 27 | ll d[maxn][maxn]; 28 | int c[maxn][maxn]; 29 | int dis[maxn]; 30 | void add(int u,int v,int c) 31 | { 32 | e[ne].u=u; e[ne].v=v; 33 | e[ne].c=c; 34 | e[ne].next=beg[u]; 35 | beg[u]=ne++; 36 | } 37 | double solve() 38 | { 39 | bool flag=false; 40 | int u,v; 41 | memset(dis,0,sizeof(dis)); //先判是否有环 42 | for(int i=1;i<=n;i++) 43 | for(int j=0;jmaxr) maxr=tmr; 81 | } 82 | if(maxr= INF) return -1; //no answer 53 | } 54 | 55 | fill(vis, vis+nv, -1); 56 | fill(id, id+nv, -1); 57 | in[root] = 0; 58 | int cnt = 0; 59 | for(int i=0; i 2 | #include 3 | #include 4 | #include 5 | #define maxn 5010 6 | #define inf 2000000000 7 | using namespace std; 8 | 9 | struct edge{ 10 | int v,c,w,next; 11 | }; 12 | vector e; 13 | int beg[maxn]; 14 | // 15 | int n,m,st,ed,k,n2,minCost,maxFlow; 16 | int matrix[60][60]; 17 | //spfa 18 | int pre_d[maxn],pre_e[maxn]; 19 | int dis[maxn]; 20 | bool inq[maxn]; 21 | // 22 | void add(int x,int y,int c,int w) 23 | { 24 | int nE=e.size(); 25 | e.push_back(edge()); 26 | e[nE].v=y; 27 | e[nE].c=c; 28 | e[nE].w=w; 29 | e[nE].next=beg[x]; 30 | beg[x]=nE; 31 | } 32 | void add_edge(int x,int y,int c,int w) 33 | { 34 | add(x,y,c,w); 35 | add(y,x,0,-w); 36 | } 37 | int lb(int x,int y) 38 | { 39 | return (x-1)*n+y; 40 | } 41 | void input() 42 | { 43 | memset(beg,255,sizeof(beg)); 44 | e.resize(0); 45 | n2=n*n; 46 | for(int i=1;i<=n;++i) 47 | for(int j=1;j<=n;++j) 48 | { 49 | scanf("%d",&matrix[i][j]); 50 | add_edge(lb(i,j),lb(i,j)+n2,1,-matrix[i][j]); 51 | add_edge(lb(i,j),lb(i,j)+n2,inf,0); 52 | } 53 | st=2*n2+1; ed=2*n2+2; 54 | 55 | add_edge(st,1,k,0); 56 | add_edge(lb(n,n)+n2,ed,k,0); 57 | 58 | for(int i=1;i<=n;++i) 59 | for(int j=1;j<=n;++j) 60 | { 61 | if(j que; 69 | memset(pre_d,0,sizeof(pre_d)); 70 | memset(pre_e,0,sizeof(pre_e)); 71 | memset(inq,0,sizeof(inq)); 72 | 73 | for(int i=1;i<=n;++i) dis[i]=inf; 74 | inq[st]=true; dis[st]=0; 75 | que.push(st); 76 | while(!que.empty()) 77 | { 78 | int x=que.front(); 79 | que.pop(); 80 | for(int i=beg[x];i!=-1;i=e[i].next) 81 | if(e[i].c){ 82 | int v=e[i].v; 83 | if(dis[x]+e[i].w 10 | #include 11 | #include 12 | #define maxn 50010 13 | using namespace std; 14 | 15 | struct edge{ 16 | int v,next; 17 | int id; 18 | }; 19 | edge e[2*maxn]; 20 | int beg[maxn],ne; 21 | int n; 22 | int mpath[maxn][2],mwho[maxn][2],maxpath[maxn]; 23 | int mostpath[maxn][3],mostwho[maxn][3]; 24 | int ans[maxn]; 25 | bool chkmax(int &x,int y) 26 | { 27 | if(y>x){ 28 | x=y; 29 | return true; 30 | }else return false; 31 | } 32 | bool chkmin(int &x,int y) 33 | { 34 | if(yi;j--) most[j]=most[j-1],who[j]=who[j-1]; 67 | most[i]=newval; 68 | who[i]=someone; 69 | break; 70 | } 71 | } 72 | void dfs1(int fa,int x) 73 | { 74 | maxpath[x]=0; 75 | memset(mostpath[x],0,sizeof(mostpath[x])); 76 | memset(mostwho[x],0,sizeof(mostwho[x])); 77 | memset(mpath[x],0,sizeof(mpath[x])); 78 | memset(mwho[x],0,sizeof(mwho[x])); 79 | for(int i=beg[x];i!=-1;i=e[i].next) 80 | if(e[i].v!=fa){ 81 | int v=e[i].v; 82 | dfs1(x,v); 83 | chkmax(maxpath[x],maxpath[v]); 84 | update(mpath[x],maxpath[v],mwho[x],v,2); //要记录儿子最长路的前2个 85 | update(mostpath[x],mostpath[v][0]+1,mostwho[x],v,3); //求最长路前3个 86 | } 87 | chkmax(maxpath[x],mostpath[x][0]+mostpath[x][1]);//有可能最长路是两个儿子相连 88 | } 89 | //选取most中不是v的前2个 90 | void selectmost2(int most[],int who[],int v,int d[]) 91 | { 92 | int cnt=0; 93 | d[0]=d[1]=0; 94 | for(int i=0;i<3 && cnt<2 ;i++) 95 | if(who[i]!=v) d[cnt++]=most[i]; 96 | } 97 | void refresh(int id,int len1,int len2) 98 | { 99 | len1++; len2++; 100 | int maxval=max(len1-1,len2-1); 101 | maxval=max(maxval,len1/2+len2/2+1); 102 | ans[id]=maxval; 103 | } 104 | void dfs2(int fa,int x,int fmaxpath,int flpath) 105 | { 106 | for(int i=beg[x];i!=-1;i=e[i].next) 107 | if(e[i].v!=fa) 108 | { 109 | int v=e[i].v; 110 | int d[2]; 111 | selectmost2(mostpath[x],mostwho[x],v,d); 112 | int val=max(flpath+d[0],d[0]+d[1]); //更新x这边的最长路 113 | val=max(val,fmaxpath); 114 | if(v==mwho[x][0]) val=max(val,mpath[x][1]); //也许某个儿子的子树最长路最长 115 | else val=max(val,mpath[x][0]); 116 | refresh(e[i].id,val,maxpath[v]); 117 | dfs2(x,v,val,max(flpath,d[0])+1); 118 | } 119 | } 120 | void output() 121 | { 122 | for(int i=0;i 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define CHARSET 256 8 | #define NONE -1 9 | #define MAXN 40000 10 | 11 | static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 12 | using namespace std; 13 | // 14 | int trie[MAXN][CHARSET]; 15 | int lab[MAXN]; 16 | int fail[MAXN]; 17 | bool collect[MAXN]; 18 | int root,size; 19 | // 20 | int n,m; 21 | int keyword[2200]; 22 | int word[2200]; 23 | bool ans[520]; 24 | char str[2200]; 25 | 26 | int eval(char ch) 27 | { 28 | for(int i=0;cb64[i];i++) 29 | if(cb64[i]==ch) return i; 30 | } 31 | void decode(char *str,int res[]) 32 | { 33 | int buf=0,cnt=0; 34 | for(int i=0;str[i] && str[i]!='=';i++) 35 | { 36 | int val=eval(str[i]); 37 | for(int j=5;j>=0;j--){ 38 | cnt++; 39 | assert(val<64); 40 | if(val & (1< que; 80 | fail[root]=0; 81 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | #define LIM 100 6 | using namespace std; 7 | struct TRIE{ 8 | int pre; 9 | int next[50]; 10 | bool end; 11 | }; 12 | int n,m,p; 13 | int has[500],num; 14 | vector trie; 15 | int f[51][110][LIM]; 16 | void trie_insert(int cur[],int len) 17 | { 18 | int x=1,i=0; 19 | while(i que; 78 | trie[1].pre=1; 79 | for(int i=0;iw) w=b[0]; 103 | int add=0; 104 | for(int i=1;i<=w;++i) 105 | { 106 | a[i]=a[i]+b[i]+add; 107 | add=a[i]/10; 108 | a[i]%=10; 109 | } 110 | while(add){ 111 | a[++w]=add%10; 112 | add/=10; 113 | } 114 | if(w>a[0]) a[0]=w; 115 | } 116 | void solve() 117 | { 118 | vector > e; 119 | queue que; 120 | que.push(1); 121 | while(!que.empty()) 122 | { 123 | int x=que.front(); que.pop(); 124 | for(int i=0;i=1;--i) printf("%d",ans[i]); 152 | printf("\n"); 153 | } 154 | } 155 | int main() 156 | { 157 | freopen("u1158.in","r",stdin); 158 | input(); 159 | trie_pre_cal(); 160 | solve(); 161 | return 0; 162 | } 163 | -------------------------------------------------------------------------------- /字符串/bob用new_lcp求最长前缀.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/字符串/bob用new_lcp求最长前缀.cpp -------------------------------------------------------------------------------- /字符串/hdu2222_AC自动机.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define maxa 26 //最大字符集 5 | using namespace std; 6 | 7 | struct node{ 8 | node *fail; //定义失败指针 9 | node *next[maxa]; //trie指针 10 | int count; 11 | node(){ 12 | fail=NULL; 13 | count=0; 14 | memset(next,0,sizeof(next)); 15 | } 16 | }; 17 | node *root; 18 | int n,m; 19 | int ans; 20 | char keyword[60]; 21 | char word[1000010]; 22 | int cs; 23 | void insert(char *str,node *p) //构造trie 24 | { 25 | for(int i=0;str[i];i++) 26 | { 27 | int idx=str[i]-'a'; 28 | if(!p->next[idx]) p=p->next[idx]=new node(); 29 | else p=p->next[idx]; 30 | } 31 | p->count++; 32 | } 33 | void input() 34 | { 35 | scanf("%d",&n); 36 | root=new node(); 37 | for(int i=0;i que; 47 | que.push(root); 48 | root->fail=NULL; 49 | while(!que.empty()) 50 | { 51 | node *p=que.front(); 52 | que.pop(); 53 | for(int i=0;inext[i]) 55 | { 56 | node *q; 57 | //ac自动机的精华所在,类似于kmp的寻找fail位置一样 58 | for(q=p->fail;q && !q->next[i] ; q=q->fail) ; 59 | p->next[i]->fail=(!q?root:q->next[i]);//如果找到的是一个空指针,那么fail指向根 60 | que.push(p->next[i]);//加入到队列中 61 | } 62 | } 63 | } 64 | void cal_count() //计算某单词出现的次数,实际做的时候根据题目具体情况决定,对于后缀包含的情况要具体而定 65 | { 66 | node *p=root; 67 | ans=0; 68 | for(int i=0;word[i];++i) 69 | { 70 | int idx=word[i]-'a'; 71 | while (p && !p->next[idx]) p=p->fail; 72 | if(!p) p=root; 73 | else p=p->next[idx]; 74 | node *q=p; 75 | while(q && q->count!=-1){ //把所有被该后缀包含的所有单词都算进去 76 | ans+=q->count; 77 | q->count=-1; 78 | q=q->fail; 79 | } 80 | } 81 | } 82 | int main() 83 | { 84 | freopen("hdu2222.in","r",stdin); 85 | scanf("%d",&cs); 86 | while(cs--) 87 | { 88 | input(); 89 | cal_fail(); 90 | cal_count(); 91 | printf("%d\n",ans); 92 | } 93 | return 0; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /字符串/kmp_pku3461.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int n,m; 7 | char s[10010],t[1000010]; 8 | int pre[10010]; 9 | void cal_pre() 10 | { 11 | int j=-1; 12 | n=strlen(s); 13 | for(int i=0;i=0 && s[i]!=s[j]) 17 | j=pre[j]; 18 | j++; 19 | } 20 | pre[n]=j; 21 | } 22 | int cal_match() 23 | { 24 | m=strlen(t); 25 | int j=0; 26 | int cnt=0; 27 | for(int i=0;i=0 && s[j]!=t[i]) //跳出循环后,s[j]==t[i],而且默认s[-1]是任意通配符 30 | j=pre[j]; 31 | if(j==n-1) cnt++,j=pre[j+1]; 32 | else j++; 33 | } 34 | return cnt; 35 | } 36 | int main() 37 | { 38 | freopen("pku3461.in","r",stdin); 39 | int cs; 40 | scanf("%d",&cs); 41 | while(cs--) 42 | { 43 | scanf("%s%s",s,t); 44 | cal_pre(); 45 | int ans=cal_match(); 46 | printf("%d\n",ans); 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /字符串/trie图_map_u1269.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | typedef map::iterator IT; 8 | struct TRIE{ 9 | int pre,dep; 10 | int end; 11 | map next; 12 | TRIE() 13 | { 14 | end=0; 15 | dep=0; 16 | next.clear(); 17 | } 18 | }; 19 | vector trie; 20 | int n,m; 21 | void input() 22 | { 23 | char ch; 24 | int x,tmp; 25 | scanf("%d\n",&n); 26 | trie.resize(2); 27 | trie[1].end=false; 28 | trie[1].dep=0; 29 | for(int i=0;i que; 66 | trie[1].pre=1; 67 | IT it; 68 | for(it=trie[1].next.begin();it!=trie[1].next.end();++it) 69 | { 70 | trie[it->second].pre=1; 71 | que.push(it->second); 72 | } 73 | while(!que.empty()) 74 | { 75 | int x=que.front(); que.pop(); 76 | if(trie[x].end) continue; 77 | for(it=trie[x].next.begin();it!=trie[x].next.end();++it) 78 | { 79 | que.push(it->second); 80 | pre_id=find_pre(trie[x].pre,it->first); 81 | trie[it->second].pre=pre_id; 82 | if(!trie[it->second].end && trie[pre_id].end) 83 | trie[it->second].end=2; 84 | } 85 | } 86 | } 87 | void solve() 88 | { 89 | char ch; 90 | scanf("%d",&m); 91 | int line=-1,pos=-1; 92 | for(int i=0;i 5 | #include 6 | #include 7 | #define maxa 26 8 | using namespace std; 9 | 10 | struct node{ 11 | int next[maxa]; 12 | int lab,fail; 13 | bool collect; //这个点是否被收集过 14 | node(){ 15 | memset(next,0,sizeof(next)); 16 | fail=lab=collect=0; 17 | } 18 | }; 19 | node a[250010]; 20 | int root,size; //root为1,0是个特殊点 21 | 22 | int cs,n; 23 | int que[250010],head,tail; 24 | char _word[5100010],word[5100010]; 25 | int len; 26 | bool ans[255]; 27 | 28 | void insert(int x,char *str,int num) 29 | { 30 | int idx; 31 | while(*str){ 32 | idx=str[0]-'A'; 33 | if(a[x].next[idx]) x=a[x].next[idx]; 34 | else { 35 | a[++size]=node(); 36 | x=a[x].next[idx]=size; 37 | } 38 | str++; 39 | } 40 | a[x].lab=num; 41 | } 42 | void extra(char *str1,char *str2) 43 | { 44 | len=0; 45 | int tmp=0; 46 | for(int i=0;str1[i];i++) 47 | { 48 | if(str1[i]=='['){ 49 | tmp=0; 50 | for(i++;str1[i]>='0' && str1[i]<='9';i++) 51 | tmp=tmp*10+str1[i]-'0'; 52 | while(tmp--) str2[len++]=str1[i]; 53 | i++; 54 | }else str2[len++]=str1[i]; 55 | } 56 | str2[len]=0; 57 | } 58 | void input() 59 | { 60 | scanf("%d",&n); 61 | root=size=1; 62 | a[0]=a[root]=node(); 63 | for(int i=1;i<=n;i++) 64 | { 65 | scanf("%s",word); 66 | insert(root,word,i); 67 | } 68 | scanf("%s",_word); 69 | extra(_word,word); 70 | } 71 | void cal_fail() 72 | { 73 | head=0,tail=1; 74 | que[0]=root; 75 | for(;head bfs; 33 | fail[0] = 0; 34 | for (int i = 0; i < CHARSET; ++i) { 35 | if (trie[0][i] != -1) { 36 | fail[trie[0][i]] = 0; 37 | bfs.push(trie[0][i]); 38 | } else { 39 | trie[0][i] = 0; 40 | } 41 | } 42 | while (!bfs.empty()) { 43 | int p = bfs.front(); 44 | tag[p] |= tag[fail[p]]; 45 | bfs.pop(); 46 | for (int i = 0; i < CHARSET; ++i) { 47 | if (trie[p][i] != -1) { 48 | fail[trie[p][i]] = trie[fail[p]][i]; 49 | bfs.push(trie[p][i]); 50 | } else { 51 | trie[p][i] = trie[fail[p]][i]; 52 | } 53 | } 54 | } 55 | } 56 | } ac; 57 | -------------------------------------------------------------------------------- /字符串/zju3430_ac自动机2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #define maxa 256 7 | 8 | static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 9 | 10 | using namespace std; 11 | 12 | struct node{ 13 | int fail,next[maxa]; 14 | int lab; 15 | node(){ 16 | fail=0; 17 | memset(next,0,sizeof(next)); 18 | lab=0; 19 | } 20 | }; 21 | node a[40000]; 22 | bool collect[40000]; 23 | int root,size; 24 | // 25 | int n,m; 26 | int keyword[2200]; 27 | int word[2200]; 28 | bool ans[520]; 29 | char str[2200]; 30 | void err() 31 | { 32 | int zero=0; 33 | zero=1/zero; 34 | } 35 | int eval(char ch) 36 | { 37 | for(int i=0;cb64[i];i++) 38 | if(cb64[i]==ch) return i; 39 | err(); 40 | } 41 | void decode(char *str,int res[]) 42 | { 43 | int buf=0,cnt=0; 44 | for(int i=0;str[i] && str[i]!='=';i++) 45 | { 46 | if(i>=64) err(); 47 | int val=eval(str[i]); 48 | for(int j=5;j>=0;j--){ 49 | cnt++; 50 | assert(val<64); 51 | if(val & (1<=256) err(); 55 | res[cnt/8-1]=buf; 56 | buf=0; 57 | } 58 | } 59 | } 60 | res[cnt/8]=-1; 61 | } 62 | void insert(int p,int str[],int num) 63 | { 64 | for(int i=0;str[i]!=-1;i++){ 65 | if(i>=64) err(); 66 | if(str[i]>=256) err(); 67 | int idx=str[i]; 68 | if(!a[p].next[idx]) { 69 | a[++size]=node(); 70 | p=a[p].next[idx]=size; 71 | }else p=a[p].next[idx]; 72 | } 73 | a[p].lab=num; 74 | } 75 | void input() 76 | { 77 | root=1; 78 | size=1; 79 | a[1]=node(); 80 | for(int i=1;i<=n;i++) 81 | { 82 | scanf("%s",str); 83 | if(strlen(str)>64) err(); 84 | decode(str,keyword); 85 | insert(root,keyword,i); 86 | } 87 | } 88 | void cal_fail() 89 | { 90 | queue que; 91 | que.push(root); 92 | a[root].fail=0; 93 | while(!que.empty()){ 94 | int p=que.front(); 95 | que.pop(); 96 | for(int i=0;i 2 | #include 3 | #define maxa 50010 4 | #define maxn 50010 5 | int r[maxn],w[maxa],sa2[maxn],r2[maxn],sa[maxn]; 6 | char s[maxn]; 7 | int n,k,n1,m; 8 | void input() 9 | { 10 | scanf("%s",s); 11 | n=strlen(s); 12 | 13 | for(int i=0;i=j) sa2[p++]=sa[i]-j; 30 | // 31 | memset(w,0,sizeof(w)); 32 | for(i=0;i=0;--i) r2[sa2[i]]=--w[r[sa2[i]]]; //对第一关键字进行排序,注意要倒着算 35 | // 36 | for(i=0;i0){ 52 | if(k>0) k--; 53 | for(j=sa[rank[i]-1];s[i+k]==s[j+k];++k) ; 54 | height[rank[i]]=k; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /字符串/扩展kmp.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/字符串/扩展kmp.cpp -------------------------------------------------------------------------------- /搜索/dancinglink跳舞链 hust 1017.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define INF 1000000000 5 | #define N 1010 6 | using namespace std; 7 | int n,m; 8 | int a[N][N],b[N][N]; 9 | int l[N*N],r[N*N],c[N*N],u[N*N],d[N*N],name[N*N]; 10 | //c是表示该点所属的列,name则表示该节点的一些属性,可以是行,也可以是所代表的取的值。 11 | bool used[N*N]; 12 | int s[N],o[N]; 13 | int h,tot; 14 | void add(int x,int &head,int flag) /*add x to head,flag==0 add row*/ 15 | { 16 | if(flag==0){ //row 17 | if(head==-1) //行的第一个 18 | { 19 | head=x; 20 | l[x]=r[x]=x; 21 | } 22 | l[x]=l[head]; 23 | r[l[head]]=x; 24 | r[x]=head; 25 | l[head]=x; 26 | }else{ 27 | u[x]=u[head]; 28 | d[u[head]]=x; 29 | d[x]=head; 30 | u[head]=x; 31 | } 32 | } 33 | void input() 34 | { 35 | int x; 36 | tot=h=0; 37 | l[h]=r[h]=h; 38 | for(int j=1;j<=m;j++) 39 | { 40 | add(++tot,h,0); 41 | u[tot]=d[tot]=c[tot]=tot; 42 | } 43 | memset(s,0,sizeof(s)); 44 | for(int i=1;i<=n;i++) 45 | { 46 | int curhead=-1,num; 47 | scanf("%d",&num); 48 | for(int j=1;j<=num;j++) 49 | { 50 | scanf("%d",&x); 51 | if(j==1) { 52 | add(++tot,curhead,0); 53 | add(tot,x,1); 54 | c[curhead]=x; s[x]++; name[curhead]=i; //这里不要忘记了添加c,name,s的值 55 | }else{ 56 | tot++; 57 | c[tot]=x; name[tot]=i; s[x]++; 58 | add(tot,curhead,0); 59 | add(tot,c[tot],1); 60 | } 61 | } 62 | } 63 | memset(used,0,sizeof(used)); 64 | } 65 | 66 | void cover(int col) 67 | { 68 | r[l[col]]=r[col]; 69 | l[r[col]]=l[col]; 70 | for(int row=d[col];row!=col;row=d[row]) 71 | for(int j=r[row];j!=row;j=r[j]) 72 | { 73 | u[d[j]]=u[j]; 74 | d[u[j]]=d[j]; 75 | s[c[j]]--; 76 | } 77 | } 78 | void uncover(int col) 79 | { 80 | for(int row=u[col];row!=col;row=u[row]) 81 | for(int j=l[row];j!=row;j=l[j]) 82 | { 83 | u[d[j]]=j; 84 | d[u[j]]=j; 85 | s[c[j]]++; 86 | } 87 | l[r[col]]=col; 88 | r[l[col]]=col; 89 | } 90 | void output() 91 | { 92 | int num=0; 93 | for(int i=1;i<=n;i++) 94 | num+=used[i]; 95 | printf("%d",num); 96 | for(int i=1;i<=n;++i) 97 | if(used[i]) printf(" %d",i); 98 | printf("\n"); 99 | } 100 | bool search() 101 | { 102 | if(r[h]==h) { 103 | output(); 104 | return true; 105 | }else{ 106 | //select minimal column 107 | int mm=INF,col; 108 | for(int i=r[h];i!=h;i=r[i]) 109 | if(s[i] 2 | #include 3 | #include 4 | #define INF 1000000000 5 | #define N 300000 6 | using namespace std; 7 | int n,m; 8 | int l[N],r[N],c[N],u[N],d[N],name[N];//c是表示该点所属的列,name则表示所属的行 9 | bool used[N]; 10 | int s[N]; 11 | int h,tot; 12 | char str[100]; 13 | int ans[10][10]; 14 | void add(int x,int &head,int flag) /*add x to head,flag==0 add row*/ 15 | { 16 | if(flag==0){ //row 17 | if(head==-1) //行的第一个 18 | { 19 | head=x; 20 | l[x]=r[x]=x; 21 | } 22 | l[x]=l[head]; 23 | r[l[head]]=x; 24 | r[x]=head; 25 | l[head]=x; 26 | }else{ 27 | u[x]=u[head]; 28 | d[u[head]]=x; 29 | d[x]=head; 30 | u[head]=x; 31 | } 32 | } 33 | void input() 34 | { 35 | tot=h=0; 36 | l[h]=r[h]=h; 37 | for(int j=1;j<=81*4;j++) 38 | { 39 | add(++tot,h,0); 40 | u[tot]=d[tot]=c[tot]=tot; 41 | } 42 | memset(s,0,sizeof(s)); 43 | for(int i=1;i<=81;i++) 44 | { 45 | int row=(i-1)/9+1,col=(i-1)%9+1,grid=(row-1)/3*3+(col-1)/3+1; 46 | //printf("%d %d %d\n",row,col,grid); 47 | if(str[i-1]!='.'){ 48 | int curhead=-1; 49 | int j=str[i-1]-'0'; 50 | add(++tot,curhead,0); add(tot,c[(row-1)*9+j],1); c[tot]=(row-1)*9+j; 51 | s[c[tot]]++; name[tot]=row*100+col*10+j; 52 | 53 | add(++tot,curhead,0); add(tot,c[81+(col-1)*9+j],1); c[tot]=81+(col-1)*9+j; 54 | s[c[tot]]++; name[tot]=row*100+col*10+j; 55 | 56 | add(++tot,curhead,0); add(tot,c[81*2+(grid-1)*9+j],1); c[tot]=81*2+(grid-1)*9+j; 57 | s[c[tot]]++; name[tot]=row*100+col*10+j; 58 | 59 | add(++tot,curhead,0); add(tot,c[81*3+i],1); c[tot]=81*3+i; 60 | s[c[tot]]++; name[tot]=row*100+col*10+j; 61 | }else{ 62 | int curhead; 63 | for(int j=1;j<=9;j++) 64 | { 65 | curhead=-1; 66 | add(++tot,curhead,0); add(tot,c[(row-1)*9+j],1); c[tot]=(row-1)*9+j; 67 | s[c[tot]]++; name[tot]=row*100+col*10+j; 68 | 69 | add(++tot,curhead,0); add(tot,c[81+(col-1)*9+j],1); c[tot]=81+(col-1)*9+j; 70 | s[c[tot]]++; name[tot]=row*100+col*10+j; 71 | 72 | add(++tot,curhead,0); add(tot,c[81*2+(grid-1)*9+j],1); c[tot]=81*2+(grid-1)*9+j; 73 | s[c[tot]]++; name[tot]=row*100+col*10+j; 74 | 75 | add(++tot,curhead,0); add(tot,c[81*3+i],1); c[tot]=81*3+i; 76 | s[c[tot]]++; name[tot]=row*100+col*10+j; 77 | } 78 | } 79 | } 80 | memset(used,0,sizeof(used)); 81 | memset(ans,0,sizeof(ans)); 82 | } 83 | 84 | void cover(int col) 85 | { 86 | r[l[col]]=r[col]; 87 | l[r[col]]=l[col]; 88 | for(int row=d[col];row!=col;row=d[row]) 89 | for(int j=r[row];j!=row;j=r[j]) 90 | { 91 | u[d[j]]=u[j]; 92 | d[u[j]]=d[j]; 93 | s[c[j]]--; 94 | } 95 | } 96 | void uncover(int col) 97 | { 98 | for(int row=u[col];row!=col;row=u[row]) 99 | for(int j=l[row];j!=row;j=l[j]) 100 | { 101 | u[d[j]]=j; 102 | d[u[j]]=j; 103 | s[c[j]]++; 104 | } 105 | l[r[col]]=col; 106 | r[l[col]]=col; 107 | } 108 | void output() 109 | { 110 | int cnt=-1; 111 | for(int i=1;i<=9;i++) 112 | for(int j=1;j<=9;j++) 113 | { 114 | cnt++; 115 | if(str[cnt]=='.') str[cnt]=ans[i][j]+'0'; 116 | } 117 | printf("%s\n",str); 118 | } 119 | bool search() 120 | { 121 | if(r[h]==h) { 122 | output(); 123 | return true; 124 | }else{ 125 | //select minimal column 126 | int mm=INF,col; 127 | for(int i=r[h];i!=h;i=r[i]) 128 | if(s[i]= 8; nKeyLength -= 8) { 9 | hash = ((hash << 5) + hash) + *arKey++; 10 | hash = ((hash << 5) + hash) + *arKey++; 11 | hash = ((hash << 5) + hash) + *arKey++; 12 | hash = ((hash << 5) + hash) + *arKey++; 13 | hash = ((hash << 5) + hash) + *arKey++; 14 | hash = ((hash << 5) + hash) + *arKey++; 15 | hash = ((hash << 5) + hash) + *arKey++; 16 | hash = ((hash << 5) + hash) + *arKey++; 17 | } 18 | switch (nKeyLength) { 19 | case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ 20 | case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ 21 | case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ 22 | case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ 23 | case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ 24 | case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */ 25 | case 1: hash = ((hash << 5) + hash) + *arKey++; break; 26 | case 0: break; 27 | EMPTY_SWITCH_DEFAULT_CASE() 28 | } 29 | return hash; 30 | } 31 | 32 | //简化版 33 | h=5381; 34 | for(int i=0;i>4))^(v[i]<<10); 42 | return s; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /数学/数值积分.cpp: -------------------------------------------------------------------------------- 1 | |>integral 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | /* simpson integral of f at [a, b] */ 9 | double simpson(double (*f)(double), double a, double b) { 10 | int n = (int)(10000 * (b - a)); n -= n % 2; 11 | double A = 0, B = 0, d = (b - a) / n; 12 | for (int i = 1; i < n; i += 2) 13 | A += f(a + i * d); 14 | for (int i = 2; i < n; i += 2) 15 | B += f(a + i * d); 16 | return (f(a) + f(b) + 4 * A + 2 * B) * d / 3; 17 | } 18 | 19 | /* romberg integral of f at [a, b] */ 20 | double romberg(double (*f)(double), double l, double r) { 21 | const int N = 18; 22 | double a[N][N], p[N]; 23 | 24 | p[0] = 1; 25 | for (int i = 1; i < N; i++) 26 | p[i] = p[i - 1] * 4; 27 | 28 | a[0][0] = (f(l) + f(r)) / 2; 29 | for (int i = 1, n = 2; i < N; i++, n <<= 1) { 30 | a[i][0] = 0; 31 | for (int j = 1; j < n; j += 2) 32 | a[i][0] += f((r - l) * j / n + l); 33 | a[i][0] += a[i - 1][0] * (n / 2); 34 | a[i][0] /= n; 35 | } 36 | for (int j = 1; j < N; j++) 37 | for (int i = 0; i < N - j; i++) 38 | a[i][j] = (a[i + 1][j - 1] * p[j] - a[i][j - 1]) / (p[j] - 1); 39 | return a[0][N - 1] * (r - l); 40 | } 41 | 42 | /* helper function of adaptive_simpsons */ 43 | double adaptive_simpsons_aux(double (*f)(double), double a, double b, double eps, 44 | double s, double fa, double fb, double fc, int depth) { 45 | double c = (a + b) / 2, h = b - a; 46 | double d = (a + c) / 2, e = (c + b) / 2; 47 | double fd = f(d), fe = f(e); 48 | double sl = (fa + 4 * fd + fc) * h / 12; 49 | double sr = (fc + 4 * fe + fb) * h / 12; 50 | double s2 = sl + sr; 51 | if (depth <= 0 || fabs(s2 - s) <= 15 * eps) 52 | return s2 + (s2 - s) / 15; 53 | return adaptive_simpsons_aux(f, a, c, eps / 2, sl, fa, fc, fd, depth - 1) + 54 | adaptive_simpsons_aux(f, c, b, eps / 2, sr, fc, fb, fe, depth - 1); 55 | } 56 | 57 | /* Adaptive Simpson's Rule, integral of f at [a, b], max error of eps, max depth of depth */ 58 | double adaptive_simpsons(double (*f)(double), double a, double b, double eps, int depth) { 59 | double c = (a + b) / 2, h = b - a; 60 | double fa = f(a), fb = f(b), fc = f(c); 61 | double s = (fa + 4 * fc + fb) * h / 6; 62 | return adaptive_simpsons_aux(f, a, b, eps, s, fa, fb, fc, depth); 63 | } 64 | -------------------------------------------------------------------------------- /数学/数论/Bernoulli数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | int gcd(int a,int b) { 6 | if(!b) return a; 7 | else return gcd(b,a%b); 8 | } 9 | int lcm(int a,int b){ 10 | return a/gcd(a,b)*b; 11 | } 12 | class Fraction{ 13 | public: 14 | int a,b; 15 | int sign(int x){ return x>0?1:-1; } 16 | Fraction():a(0),b(1){} 17 | Fraction(int x):a(x),b(1){} 18 | Fraction(int x,int y){ 19 | int m=gcd(abs(x),abs(y)); 20 | a=x/m*sign(y); 21 | if(a==0) b=1;else b=abs(y/m); 22 | } 23 | int get_denominator(){return b;} 24 | int get_numerator(){return a;} 25 | Fraction operator+(const Fraction &f){ 26 | int m=gcd(b,f.b); 27 | return Fraction(f.b/m*a+b/m*f.a,b/m*f.b); 28 | } 29 | Fraction operator-(const Fraction &f){ 30 | int m=gcd(b,f.b); 31 | return Fraction(f.b/m*a-b/m*f.a,b/m*f.b); 32 | } 33 | Fraction operator*(const Fraction &f){ 34 | int m1=gcd(abs(a),f.b); 35 | int m2=gcd(b,abs(f.a)); 36 | return Fraction((a/m1)*(f.a/m2),(b/m2)*(f.b/m1)); 37 | } 38 | Fraction operator/(const Fraction &f){ 39 | return (*this)*Fraction(f.b,f.a); 40 | } 41 | }; 42 | Fraction a[22]; 43 | int c[22][22]; 44 | int main() 45 | { 46 | freopen("pku1707.in","r",stdin); 47 | int k,m; 48 | c[0][0]=1; 49 | for(int i=1;i<=21;i++){ 50 | c[i][0]=1; c[i][i]=1; 51 | for(int j=1;j=1;i--){ 58 | a[i]=0; 59 | for(int j=i+1;j<=k+1;j++) 60 | if((j-i+1)%2==0) a[i]=a[i]+a[j]*c[j][j-i+1]; 61 | else a[i]=a[i]-a[j]*c[j][j-i+1]; 62 | a[i]=a[i]*Fraction(1,i); 63 | m=lcm(m,a[i].get_denominator()); 64 | } 65 | printf("%d ",m); //1^k+2^k+..+n^k=1/m*(co[k+1]*n^(k+1) + co[k]*n^k + ..+co[0]) 66 | //其中co[i]=a[i].a*m/a[i].b; 67 | for(int i=k+1;i>0;i--) printf("%d ",a[i].a*m/a[i].b); 68 | printf("0\n"); 69 | } 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /数学/数论/Miller_Rabin素数测试.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 该函数对2^64以内的数都能有效辨别。 3 | */ 4 | const int cstPrime[10]={2,3,5,7,11,13,17,19,23,29}; 5 | bool Miller_Rabin(ll a,ll n) 6 | { 7 | ll r=0,s=n-1; 8 | while(!(s&1)) r++,s>>=1; //n-1==2^r*s 9 | ll as=pow_mod(a,s,n); //as=a^s%n 10 | if(as==1 || as==n-1) return true; //if as==1 or as^i%n==n-1 then it is likely be prime 11 | for(int i=1;i 1 && d < n) return d; 18 | if (i == k) y = x, k *= 2; 19 | x = (mod(x, x, n) + n - c) % n; 20 | if(x==y) break; 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /数学/数论/lucas.cpp: -------------------------------------------------------------------------------- 1 | ll lucas(ll n, ll m, ll p) // C(n, m) % p 2 | { 3 | if(m == 0) return 1; 4 | if(m == 1) return n % p; 5 | ll l2 = lucas(n/p, m/p, p); 6 | 7 | n = n % p; 8 | m = m % p; 9 | // up / down = C(n, m) 10 | ll up = n! % p 11 | ll down = m ! * (n - m) ! % p; 12 | ll x, y; 13 | ext_gcd(down, p, x, y); 14 | x = (x % p + p ) % p; 15 | //down = 1/down (mod p); //求down 的逆 16 | up = up * x % p; 17 | 18 | return l2 * up % p; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /数学/数论/中国剩余定理.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define MAXN 10010 4 | using namespace std; 5 | int m[MAXN],M; 6 | int a[MAXN]; 7 | int ans,n; 8 | void extend_gcd(int a,int b,int &d,int &x,int &y) 9 | { 10 | if(!b) { d=a;x=1;y=0; } 11 | else { 12 | extend_gcd(b,a%b,d,y,x); 13 | y-=x*(a/b); 14 | } 15 | } 16 | int china(int n,int a[],int m[]) 17 | { 18 | int x,y,wi,d; 19 | int ret=0; 20 | M=1; 21 | for(int i=1;i<=n;++i) M*=m[i]; 22 | for(int i=1;i<=n;++i) 23 | { 24 | wi=M/m[i]; 25 | extend_gcd(wi,m[i],d,x,y); 26 | ret=(ret+wi*a[i]*x)%M; 27 | } 28 | return ret; 29 | } 30 | int main() 31 | { 32 | freopen("test.in","r",stdin); 33 | scanf("%d",&n); 34 | for(int i=1;i<=n;++i) 35 | scanf("%d%d",a+i,m+i); 36 | ans=china(n,a,m); 37 | printf("%d\n",ans); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /数学/数论/中国剩余定理写成类_求x^2_mod_m=1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 输入m 3 | Find out all x (<=m) that x^2 mod m=1 4 | //中国剩余定理写成类 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #define N 100 11 | #define VI vector 12 | typedef long long LL; 13 | //typedef vector VI; 14 | using namespace std; 15 | 16 | class Chn{ 17 | public: 18 | int extend_gcd(int,int,int&,int&); 19 | int mainProc(VI &x,VI &m); 20 | }; 21 | int Chn::extend_gcd(int a,int b,int& x,int& y) 22 | { 23 | if(b==0){ 24 | x=1;y=0; return a; 25 | }else{ 26 | int d=extend_gcd(b,a%b,x,y); 27 | int rx=x; 28 | x=y; 29 | y=rx-a/b*y; 30 | return d; 31 | } 32 | } 33 | int Chn::mainProc(VI &x,VI &m)// x为余数,m为mod 34 | { 35 | int k=x.size(); 36 | int M=1,ans=0; 37 | for(int i=0;i1){ 68 | p[++nP]=tm; 69 | e[nP]=1; pk[nP]=tm; 70 | M.push_back(tm); 71 | } 72 | nP++; 73 | } 74 | void distr(int cur) 75 | { 76 | if(cur==nP) { 77 | int ans=cn.mainProc(X,M); 78 | printf("%d x^2 mod m=%lld\n",ans,(LL)ans*ans%m); 79 | } 80 | else{ 81 | if(p[cur]==2) 82 | { 83 | X[cur]=1; 84 | distr(cur+1); 85 | if(e[cur]>1) 86 | { 87 | X[cur]=pk[cur]-1; 88 | distr(cur+1); 89 | } 90 | if(e[cur]>=3) 91 | { 92 | X[cur]=pk[cur]/2+1; 93 | distr(cur+1); 94 | X[cur]=pk[cur]/2-1; 95 | distr(cur+1); 96 | } 97 | } 98 | else{ 99 | X[cur]=1; 100 | distr(cur+1); 101 | X[cur]=pk[cur]-1; 102 | distr(cur+1); 103 | } 104 | } 105 | } 106 | void solve() 107 | { 108 | X.resize(nP,0); 109 | distr(0); 110 | printf("\n"); 111 | } 112 | int main() 113 | { 114 | scanf("%d",&m); 115 | preWork(); 116 | solve(); 117 | return 0; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /数学/数论/中国剩余定理(不互质情况)pku2891.cpp: -------------------------------------------------------------------------------- 1 | 2 | ll chinese_remain(vector > &vec) 3 | { 4 | ll m1, a1, m2, a2; 5 | ll y, z, d; 6 | a1 = vec[0].first; 7 | m1 = vec[0].second; 8 | for(int i=1; i 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #define MOD 1000003 12 | const int T=100000000; 13 | typedef long long ll; 14 | using namespace std; 15 | struct NODE{ 16 | NODE(int _bx=0,int _x=0,int _next=0):bx(_bx),x(_x),next(_next){} 17 | ll bx,x; 18 | int next; 19 | }; 20 | // hash部分,写成类形式。 21 | class Hash{ 22 | int beg[MOD]; 23 | vector hash; 24 | public: 25 | Hash(){ 26 | flush(); 27 | } 28 | void flush(){ 29 | memset(beg,255,sizeof(beg)); 30 | hash.resize(0,0); 31 | } 32 | void insert(ll bx,ll x) 33 | { 34 | int pos=bx%MOD; 35 | if(get(bx)==-1) 36 | { 37 | hash.push_back(NODE(bx,x,beg[pos])); 38 | beg[pos]=hash.size()-1; 39 | } 40 | } 41 | ll get(ll bx) 42 | { 43 | int pos=bx%MOD; 44 | for(int i=beg[pos];i!=-1;i=hash[i].next) 45 | if(hash[i].bx==bx) return hash[i].x; 46 | return -1; 47 | } 48 | }; 49 | Hash tab; 50 | 51 | ll p,k,a,g,d,remain; 52 | int prime[40000],np; 53 | int pri[40000],npri; 54 | bool isPrime[40000]; 55 | vector ans; 56 | int zero=0; 57 | void pre() // 线性素数筛选。 58 | { 59 | np=0; 60 | memset(isPrime,1,sizeof(isPrime)); 61 | for(int i=2;i<40000;++i) 62 | if(isPrime[i]){ 63 | prime[++np]=i; 64 | for(int j=i*i;j<40000;j+=i) 65 | isPrime[j]=false; 66 | } 67 | } 68 | void Div(int p) //将p进行质因数分解 69 | { 70 | int tm=p-1; 71 | npri=0; 72 | for(int i=1;i<=np && tm>=prime[i] ;++i) 73 | if(tm%prime[i]==0) 74 | { 75 | pri[++npri]=prime[i]; 76 | while(tm%prime[i]==0) tm/=prime[i]; 77 | } 78 | if(tm>1) pri[++npri]=tm; 79 | } 80 | inline ll mod(ll x,ll y,ll p)//输出x*y%p 81 | { 82 | ll c=y/T,d=y%T; 83 | return (x*c%p*T%p+x*d%p)%p; 84 | 85 | } 86 | ll pow_mod(ll b,ll x,ll p)//输出 b^x mod p 87 | { 88 | ll ret=1; 89 | while(x) 90 | { 91 | if(x&1) ret=mod(ret,b,p); 92 | b=mod(b,b,p); 93 | x>>=1; 94 | } 95 | return ret; 96 | } 97 | void extend_gcd(int a,int b,ll &d,ll &x,ll &y) //扩展gcd 98 | { 99 | if(!b) { d=a; x=1; y=0; return ; } 100 | else{ 101 | extend_gcd(b,a%b,d,y,x); 102 | y-=a/b*x; 103 | } 104 | } 105 | int find_root(int p) //枚举r,寻找p的原根,要求p为1,2,4,p^e,或者2p^e,p为奇素数。 106 | { 107 | if(p==2) return 1; 108 | for(int r=2;;r++) 109 | { 110 | bool flag=true; 111 | for(int j=1;j<=npri;++j) //如果对所有r^((p-1)/pri[j]) mod p!=1,那么r是p的原根。 112 | if(pow_mod(r,(p-1)/pri[j],p)==1) { //pri[j]是p-1的素数因子 113 | flag=false; 114 | break; 115 | } 116 | if(flag) return r; 117 | } 118 | } 119 | void solve() 120 | { 121 | ll x,y,t,tm; 122 | extend_gcd(k,p-1,d,x,y); 123 | t=(p-1)/d; 124 | ans.resize(0,0); 125 | if(remain%d) return ; 126 | x=x*remain/d%(p-1); 127 | for(int i=0;i0){ 139 | for(int i=0;i>p>>k>>a) 197 | { 198 | a=a%p; 199 | if(a==0) { 200 | cout<<"1"< 2 | #include 3 | #include 4 | #define TAB_SIZE 150000 5 | #define MOD 1000007 6 | typedef long long ll; 7 | const ll T=100000000; 8 | using namespace std; 9 | struct NODE{ 10 | ll bx,x; 11 | int next; 12 | }; 13 | class Hash{ 14 | int beg[MOD]; 15 | NODE hash[TAB_SIZE]; 16 | int nH; 17 | public: 18 | Hash(){ 19 | flush(); 20 | } 21 | void flush(){ 22 | memset(beg,0,sizeof(beg)); 23 | nH=0; 24 | } 25 | void insert(ll bx,ll x) 26 | { 27 | int pos=bx%MOD; 28 | if(get(bx)==-1) 29 | { 30 | nH++; 31 | hash[nH].bx=bx; 32 | hash[nH].x=x; 33 | hash[nH].next=beg[pos]; 34 | beg[pos]=nH; 35 | } 36 | } 37 | ll get(ll bx) 38 | { 39 | int pos=bx%MOD; 40 | for(int i=beg[pos];i;i=hash[i].next) 41 | if(hash[i].bx==bx) return hash[i].x; 42 | return -1; 43 | } 44 | }; 45 | Hash tab; 46 | ll mod(ll x,ll y,ll z) //cal x*y%z 47 | { 48 | ll c=y/T,d=y%T; 49 | return (x*c%z*T%z+x*d%z)%z; 50 | } 51 | void extend_gcd(ll a,ll b,ll &d,ll &x,ll &y) 52 | { 53 | if(!b){ x=1; y=0 ; d=a ;} 54 | else { 55 | extend_gcd(b,a%b,d,y,x); 56 | y-=a/b*x; 57 | } 58 | } 59 | ll baby_giant_setp(ll b,ll n,ll p) 60 | { 61 | ll m=ceil(sqrt(p*1.0)); 62 | ll bm=1; 63 | for(int i=0;ij, i*p[j']=(i'*p[j])*p[j']=(i'*p[j'])*p[j]=i''*p[j], 其中i''>i,于是后面的i''会把这个i*p[j']的非素数都筛去,就没必要做重复工作了*/ 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /数学/龙贝格积分.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | double romberg(double a, double b, double eps, 6 | double (*f)(double)) 7 | { 8 | #define ROUND 10 9 | int m, n, i, k; 10 | double y[ROUND], h, ep, p, x, s, q; 11 | h = b - a; 12 | y[0] = h * ((*f)(a) + (*f)(b)) / 2.0; 13 | m = n = 1; 14 | ep = eps + 1.0; 15 | while(ep >= eps && m <= ROUND-1) 16 | { 17 | p = 0; 18 | for(i=0; i<=n-1; i++) 19 | { 20 | x = a + (i+0.5) * h; 21 | p = p + (*f)(x); 22 | } 23 | p = (y[0] + h*p) / 2; 24 | s = 1; 25 | for(k=1; k<=m; k++) 26 | { 27 | s = 4*s; 28 | q = (s * p - y[k-1]) / (s - 1); 29 | y[k-1] = p; 30 | p = q; 31 | } 32 | ep = fabs(q - y[m-1]); 33 | m = m+1; 34 | y[m-1] = q; 35 | n = n + n; 36 | h = h / 2; 37 | } 38 | return q; 39 | } 40 | double f(double x) 41 | { 42 | return x / (4 + x * x ); 43 | //return x*x; 44 | } 45 | int main() 46 | { 47 | double ans = romberg(0, 1, 0.000001, f); 48 | printf("%.8lf\n", ans); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /数据结构/avl平衡树.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/数据结构/avl平衡树.cpp -------------------------------------------------------------------------------- /数据结构/candy求最大子矩阵.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wizardcypress/MyAcmCodeTemplate/3307a312993df059fbcaf2bc5e833053fd12e2d1/数据结构/candy求最大子矩阵.cpp -------------------------------------------------------------------------------- /数据结构/happy线段树_懒惰标记覆盖.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define size 2*131072 4 | #define INF 2000000000 5 | using namespace std; 6 | int n,m,ll,rr,z,r1,r2; 7 | char tsk; 8 | int mx[size],num[size],c[size]; 9 | void build(int x,int l,int r) 10 | { 11 | if(l==r) 12 | { 13 | mx[x]=0;num[x]=l;c[x]=0; 14 | }else { 15 | build(x*2,l,(l+r)/2); 16 | build(x*2+1,(l+r)/2+1,r); 17 | mx[x]=c[x]=0; 18 | num[x]=num[x*2]; 19 | } 20 | } 21 | void insert(int x,int l,int r,int add) 22 | { 23 | if(rrr) return ; 24 | if(ll<=l&&rr>=r) { 25 | c[x]+=add; 26 | mx[x]+=add; 27 | }else { 28 | insert(x*2,l,(l+r)/2,add); 29 | insert(x*2+1,(l+r)/2+1,r,add); 30 | if(l=mx[x*2+1]) mx[x]=mx[x*2]+c[x],num[x]=num[x*2]; 32 | else mx[x]=mx[x*2+1]+c[x],num[x]=num[x*2+1]; 33 | } 34 | } 35 | } 36 | int find(int x,int l,int r,int &r2) 37 | { 38 | if(rrr) return -INF; 39 | if(ll<=l&&rr>=r) 40 | { 41 | r2=num[x]; 42 | return mx[x]; 43 | }else { 44 | int d1,d2,t1,t2; 45 | d1=find(x*2,l,(l+r)/2,t1); 46 | d2=find(x*2+1,(l+r)/2+1,r,t2); 47 | if(d1>=d2) { 48 | r2=t1; 49 | return d1+c[x]; 50 | }else{ 51 | r2=t2; 52 | return d2+c[x]; 53 | } 54 | } 55 | } 56 | int main() 57 | { 58 | freopen("happy.in","r",stdin); 59 | freopen("happy.out","w",stdout); 60 | while(scanf("%d%d\n",&n,&m),n+m) 61 | { 62 | memset(c,0,sizeof(c)); 63 | memset(num,0,sizeof(num)); 64 | memset(mx,0,sizeof(mx)); 65 | build(1,1,n); 66 | for(int i=1;i<=m;++i) 67 | { 68 | scanf("%c",&tsk); 69 | if(tsk=='I') { 70 | scanf("%d%d%d\n",&ll,&rr,&z); 71 | insert(1,1,n,z); 72 | } 73 | else{ 74 | scanf("%d%d\n",&ll,&rr); 75 | r1=find(1,1,n,r2); 76 | printf("%d\n",r1); 77 | ll=rr=r2; 78 | insert(1,1,n,-r1); 79 | } 80 | } 81 | } 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /数据结构/hdu1255求矩形面积交.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #define N 1010 6 | using namespace std; 7 | 8 | struct POINT{ 9 | double data; 10 | int pos; 11 | }point[4*N];//用来离散化 12 | int np; 13 | /// 14 | struct INTERVAL{//添加进线段树上的线段 15 | int x,y1,y2; 16 | int add; 17 | INTERVAL(int _x=0,int _y1=0,int _y2=0,int _add=0):x(_x),y1(_y1),y2(_y2),add(_add){} 18 | }line[2*N]; 19 | int nl; 20 | 21 | 22 | POINT cord[N][4];//坐标 23 | int c[N*16]; 24 | double cl1[N*16],cl2[N*16];//覆盖了一次和两次的长度值 25 | int n,m; 26 | int ll,rr; 27 | 28 | bool cmp(const POINT &x,const POINT &y) 29 | { 30 | return x.data0){ 76 | cl1[x]=point[r].data-point[l].data; 77 | }else{ 78 | if(l1){ 85 | cl2[x]=point[r].data-point[l].data; 86 | }else if(c[x]==1){ 87 | if(l=r) return ; 97 | if(ll<=l && r<=rr) 98 | { 99 | c[x]+=add; 100 | cal_cl1(x,l,r); 101 | cal_cl2(x,l,r); 102 | }else{ 103 | insert(x*2,l,(l+r)/2,add); 104 | insert(x*2+1,(l+r)/2,r,add); 105 | cal_cl1(x,l,r); 106 | cal_cl2(x,l,r); 107 | } 108 | } 109 | void solve() 110 | { 111 | double ans=0; 112 | memset(c,0,sizeof(c)); 113 | memset(cl1,0,sizeof(cl1)); 114 | memset(cl2,0,sizeof(cl2)); 115 | ll=line[0].y1; 116 | rr=line[0].y2; 117 | insert(1,0,np-1,line[0].add); 118 | for(int i=1;i 9 | #include 10 | #include 11 | #include 12 | #define N 4000 13 | using namespace std; 14 | int m; 15 | struct TREE{ 16 | int maxLove[4*N]; //二维线段树 17 | }mm[400]; 18 | 19 | struct POINT{ 20 | double data; 21 | int pos; 22 | }; 23 | 24 | POINT cord[100000][4]; 25 | 26 | int instr[1000000]; 27 | int n; 28 | int tg1,tg2; 29 | int ll1,rr1,ll2,rr2; 30 | 31 | void input() 32 | { 33 | char task; 34 | for(int i=0;ir) return ; 57 | if(l==r){ 58 | //这一句相当重要,因为对于第一区间而言,第二区间的一个格子是代表了实际的一行格子 59 | //所以更新时是需要进行判断的。 60 | if(keypos>curT.maxLove[x]) 61 | curT.maxLove[x]=keypos; 62 | return ; 63 | } 64 | insert2(curT,x*2,l,(l+r)/2,keypos); 65 | insert2(curT,x*2+1,(l+r)/2+1,r,keypos); 66 | curT.maxLove[x]=curT.maxLove[x*2]; 67 | if(curT.maxLove[x*2+1]>curT.maxLove[x]) curT.maxLove[x]=curT.maxLove[x*2+1]; 68 | } 69 | void insert1(int x,int l,int r,int key) 70 | { 71 | if(tg1r) return ; 72 | if(l==r){ 73 | insert2(mm[x],1,0,1000,key); 74 | return ; 75 | } //每一个祖先区间都要进行第二区间更新 76 | insert2(mm[x],1,0,1000,key);//ancestor change 77 | 78 | insert1(x*2,l,(l+r)/2,key); 79 | insert1(x*2+1,(l+r)/2+1,r,key); 80 | } 81 | int find2(TREE &curT,int x,int l,int r) 82 | { 83 | if(rr2d2) return d1; 90 | else return d2; 91 | } 92 | } 93 | int find1(int x,int l,int r) 94 | { 95 | if(rr1d2) return d1; 102 | else return d2; 103 | } 104 | } 105 | void solve() 106 | { 107 | int ans; 108 | for(int i=0;i<400;++i) 109 | memset(mm[i].maxLove,255,sizeof(mm[i].maxLove)); 110 | 111 | for(int i=0;irr1) swap(ll1,rr1); 123 | if(ll2>rr2) swap(ll2,rr2); 124 | ans=find1(1,0,100); 125 | if(ans<0) printf("-1\n"); 126 | else printf("%.1f\n",ans*1.0/10); 127 | } 128 | } 129 | } 130 | int main() 131 | { 132 | freopen("hdu1823.in","r",stdin); 133 | while(scanf("%d\n",&m),m) 134 | { 135 | input(); 136 | solve(); 137 | } 138 | return 0; 139 | } 140 | -------------------------------------------------------------------------------- /数据结构/hdu3487_伸展树.cpp: -------------------------------------------------------------------------------- 1 | //伸展树 2 | #include 3 | #include 4 | #include 5 | #define MAXN 300010 6 | #define MAXM 300010 7 | #define Type int 8 | using namespace std; 9 | 10 | int n,m,a,b,c,cnt; 11 | char task[20]; 12 | 13 | int size,root; // 树的大小和根的编号 14 | int s[MAXN],left[MAXN],right[MAXN]; //儿子个数,左儿子,右儿子 15 | Type data[MAXN]; //节点的值 16 | int rev[MAXN]; //是否翻转 17 | int fa[MAXN]; //父亲值 18 | //splayTree () { clear(); } 19 | void clear() { 20 | s[0]=left[0]=right[0]=rev[0]=fa[0]=root=size=0; 21 | } 22 | void leftrotate(int x) //左旋转 23 | { 24 | int y=right[x]; 25 | if(x==left[fa[x]]) left[fa[x]]=y; 26 | else right[fa[x]]=y; 27 | fa[y]=fa[x]; fa[x]=y; fa[left[y]]=x; 28 | right[x]=left[y]; left[y]=x; 29 | s[y]=s[x]; 30 | s[x]=s[left[x]]+s[right[x]]+1; 31 | } 32 | void rightrotate(int x) //右旋转 33 | { 34 | int y=left[x]; 35 | if(x==left[fa[x]]) left[fa[x]]=y; 36 | else right[fa[x]]=y; 37 | fa[y]=fa[x]; fa[x]=y; fa[right[y]]=x; 38 | left[x]=right[y]; right[y]=x; 39 | s[y]=s[x]; 40 | s[x]=s[left[x]]+s[right[x]]+1; 41 | } 42 | void pushDown(int &x) //向下传递翻转消息 43 | { 44 | if(x && rev[x]){ 45 | if(left[x]) rev[left[x]]^=1; 46 | if(right[x]) rev[right[x]]^=1; 47 | rev[x]=0; 48 | int tmp=left[x]; left[x]=right[x]; right[x]=tmp; 49 | } 50 | } 51 | int select(int x,int kth) //返回第kth个的编号 52 | { 53 | int cnt=0; 54 | pushDown(x); 55 | pushDown(left[x]); 56 | pushDown(right[x]); 57 | while(s[left[x]]+1!=kth){ 58 | cnt++; 59 | ensure(cnt<=n); 60 | if(kth<=s[left[x]]) x=left[x]; 61 | else { 62 | kth=kth-(s[left[x]]+1); 63 | x=right[x]; 64 | } 65 | pushDown(x); 66 | pushDown(left[x]); 67 | pushDown(right[x]); 68 | } 69 | return x; 70 | } 71 | //先求得第kth个的编号,然后从下而上的旋转,避免递归导致栈溢出 72 | //splay(x,kth)的含义为把第kth个旋转到x上 73 | void splay(int &x,int kth) 74 | { 75 | int z=select(x,kth); //find the kth num 76 | int fx=fa[x]; //super root 77 | int y,g; 78 | while(fa[z]!=fx){ 79 | y=fa[z]; 80 | g=fa[y]; 81 | if(fa[z]==x){ 82 | if(left[x]==z) rightrotate(x); 83 | else leftrotate(x); 84 | }else if(left[y]==z && left[g]==y){ 85 | rightrotate(g); 86 | rightrotate(y); 87 | }else if(right[y]==z && left[g]==y){ 88 | leftrotate(y); 89 | rightrotate(g); 90 | }else if(right[y]==z && right[g]==y){ 91 | leftrotate(g); 92 | leftrotate(y); 93 | }else if(left[y]==z && right[g]==y){ 94 | rightrotate(y); 95 | leftrotate(g); 96 | } 97 | } 98 | x=z; 99 | } 100 | void build(int &x,int l,int r) 101 | { 102 | if(l>r) return ; 103 | int mid=(l+r)>>1; 104 | x=++size; 105 | data[x]=mid; 106 | left[x]=right[x]=rev[x]=fa[x]=0; 107 | 108 | build(left[x],l,mid-1); 109 | if(l<=mid-1) fa[left[x]]=x; 110 | 111 | build(right[x],mid+1,r); 112 | if(mid+1<=r) fa[right[x]]=x; 113 | 114 | s[x]=s[left[x]]+s[right[x]]+1; 115 | } 116 | void travel(int x) 117 | { 118 | pushDown(x); 119 | if(left[x]) travel(left[x]); 120 | cnt++; 121 | if(cnt>1) printf(" "); 122 | printf("%d",data[x]); 123 | if(right[x]) travel(right[x]); 124 | } 125 | int main() 126 | { 127 | //freopen("hdu3487.in","r",stdin); 128 | while(scanf("%d%d",&n,&m),n>0 && m>0) 129 | { 130 | 131 | clear(); 132 | build(root,1,n); 133 | for(int i=1;i<=m;i++) 134 | { 135 | scanf("%s",task); 136 | if(task[0]=='C'){ 137 | scanf("%d%d%d",&a,&b,&c); //cut a~b and insert after c 138 | if(a==1 && b==n) continue; 139 | int rec; 140 | if(a==1){ 141 | splay(root,b+1); 142 | rec=left[root]; 143 | s[root]-=s[rec]; 144 | left[root]=0; 145 | }else if(b==n){ 146 | splay(root,a-1); 147 | rec=right[root]; 148 | s[root]-=s[rec]; 149 | right[root]=0; 150 | }else { 151 | splay(root,a-1); 152 | splay(right[root],b-s[left[root]]); 153 | rec=left[right[root]]; 154 | left[right[root]]=0; 155 | s[root]-=s[rec]; 156 | s[right[root]]-=s[rec]; 157 | } 158 | if(c==0){ 159 | splay(root,1); 160 | left[root]=rec; 161 | s[root]+=s[rec]; 162 | fa[rec]=root; 163 | }else if(c==s[root]){ 164 | splay(root,c); 165 | right[root]=rec; 166 | s[root]+=s[rec]; 167 | fa[rec]=root; 168 | }else{ 169 | splay(root,c); 170 | splay(right[root],c-s[left[root]]); 171 | left[right[root]]=rec; 172 | fa[rec]=right[root]; 173 | s[right[root]]+=s[rec]; 174 | s[root]+=s[rec]; 175 | } 176 | }else { 177 | scanf("%d%d",&a,&b); //flip a~b 178 | if(a==1 && b==n) rev[root]^=1; 179 | else if(a==1){ 180 | splay(root,b+1); 181 | rev[left[root]]^=1; 182 | }else if(b==n){ 183 | splay(root,a-1); 184 | rev[right[root]]^=1; 185 | }else { 186 | splay(root,a-1); 187 | splay(right[root],b-s[left[root]]); 188 | rev[left[right[root]]]^=1; 189 | } 190 | } 191 | } 192 | cnt=0; 193 | travel(root); 194 | printf("\n"); 195 | } 196 | return 0; 197 | } 198 | -------------------------------------------------------------------------------- /数据结构/hdu3563_矩形切割.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define MAXD 12 5 | #define MOD 14121413 6 | using namespace std; 7 | typedef long long cord_t;//cordinate type 8 | struct REG{ 9 | cord_t st[MAXD],ed[MAXD]; 10 | REG *pre,*next; 11 | }; 12 | REG *head,*tail,*cur; 13 | int n; 14 | int dim; 15 | cord_t ans; 16 | bool cross(REG &x,REG &y) 17 | { 18 | for(int i=0;ipre=head; 30 | cur->next=head->next; 31 | head->next->pre=cur; 32 | head->next=cur; 33 | } 34 | void cut(REG x,REG y) 35 | { 36 | for(int i=0;ipre=tail->next=NULL; 62 | head->next=tail; 63 | tail->pre=head; 64 | } 65 | void solve() 66 | { 67 | cur=new REG; 68 | for(int i=1;i<=n;++i) 69 | { 70 | for(int j=0;jst[j]); 71 | for(int j=0;jed[j]); 72 | 73 | for(int j=0;jst[j]; 76 | int d2=cur->ed[j]; 77 | cur->st[j]=min(d1,d2); 78 | cur->ed[j]=max(d1,d2); 79 | } 80 | for(REG *q=head->next;q!=tail;q=q->next) 81 | { 82 | if(cross(*q,*cur)){ 83 | cut(*q,*cur); 84 | /* delete q */ 85 | q->pre->next=q->next; 86 | q->next->pre=q->pre; 87 | delete q; 88 | } 89 | } 90 | /* add cur before tail */ 91 | add(*cur); 92 | } 93 | 94 | ans=0; 95 | for(REG *q=head->next;q!=tail;q=q->next) 96 | { 97 | cord_t sum=1; 98 | for(int i=0;ied[i]-q->st[i])%MOD))%MOD; 100 | ans=(ans+sum)%MOD; 101 | } 102 | printf("%I64d\n",ans); 103 | } 104 | void clear() 105 | { 106 | for(REG *q=head->next;q!=tail;q=q->next) 107 | delete q->pre; 108 | delete tail; 109 | } 110 | int main() 111 | { 112 | freopen("hdu3563.in","r",stdin); 113 | while(scanf("%d%d",&n,&dim)!=EOF) 114 | { 115 | init(); 116 | solve(); 117 | clear(); 118 | } 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /数据结构/hdu3627_动态找出右下角最靠近的点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #define maxn 200010 7 | using namespace std; 8 | struct TASK{ 9 | int task; /*1 add; 2 remove; 3 find*/ 10 | int x,y; 11 | int idx,idy; 12 | }; 13 | struct HNODE{ 14 | int val; 15 | int id; 16 | bool operator<(const HNODE &that)const 17 | { 18 | return val st[maxn]; 26 | int maxy[maxn*4]; 27 | int mdx; 28 | int n; 29 | 30 | void input() 31 | { 32 | char cmd[100]; 33 | int x,y; 34 | for(int i=0;imaxy[v]) maxy[v]=y; 76 | }else { 77 | if(x<=(l+r)/2) insert(v*2,l,(l+r)/2,x,y); 78 | else insert(v*2+1,(l+r)/2+1,r,x,y); 79 | if(maxy[v*2]>maxy[v*2+1]) maxy[v]=maxy[v*2]; 80 | else maxy[v]=maxy[v*2+1]; 81 | } 82 | 83 | } 84 | void remove(int v,int l,int r,int &x,int &y) 85 | { 86 | if(x::iterator it=st[l].end(); 92 | it--; 93 | maxy[v]=*it; 94 | } 95 | }else { 96 | if(x<=(l+r)/2) remove(v*2,l,(l+r)/2,x,y); 97 | else remove(v*2+1,(l+r)/2+1,r,x,y); 98 | if(maxy[v*2]>maxy[v*2+1]) maxy[v]=maxy[v*2]; 99 | else maxy[v]=maxy[v*2+1]; 100 | } 101 | } 102 | bool find(int v,int l,int r,int &x,int &y,int &retx,int &rety) 103 | { 104 | if(x>=r) return false; 105 | if(maxy[v]<=y) return false; 106 | if(l==r) 107 | { 108 | set::iterator it=st[l].upper_bound(y); 109 | if(it==st[l].end()) return false; 110 | retx=l; 111 | rety=*it; 112 | return true; 113 | }else{ 114 | if(find(v*2,l,(l+r)/2,x,y,retx,rety)) return true; 115 | else return find(v*2+1,(l+r)/2+1,r,x,y,retx,rety); 116 | } 117 | } 118 | void solve() 119 | { 120 | memset(maxy,255,sizeof(maxy)); 121 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | #define MAXN 20010 6 | using namespace std; 7 | typedef long long LL; 8 | struct point{ 9 | int x,y1,y2; 10 | int add; 11 | point(){} 12 | point(int ix,int iy1,int iy2,int iadd):x(ix),y1(iy1),y2(iy2),add(iadd){} 13 | }a[MAXN]; 14 | point tmp; 15 | int n,m,x1,y1,x2,y2,ll,rr,mxy; 16 | int cl[65546],c[65546]; 17 | int add; 18 | LL ans; 19 | int mxl=-1; 20 | bool cmp(const point &p1,const point &p2) 21 | { 22 | return p1.xmxy) mxy=y2; 33 | if(y1>mxy) mxy=y1; 34 | a[i]=point(x1,y1,y2,1); 35 | a[i+n]=point(x2,y1,y2,-1); 36 | } 37 | sort(a+1,a+2*n+1,cmp); 38 | } 39 | void insert(int x,int l,int r) 40 | { 41 | if(r=r){ 43 | if(add>0) { 44 | c[x]++; cl[x]=r-l+1; 45 | return ; 46 | }else { 47 | c[x]--; 48 | if(!c[x]) 49 | { 50 | if(l 2 | #include 3 | #include 4 | #define MAXD 2 5 | using namespace std; 6 | typedef double cord_t;//cordinate type 7 | struct REG{ 8 | cord_t st[MAXD],ed[MAXD]; 9 | REG *pre,*next; 10 | }; 11 | REG *head,*tail,*cur; 12 | int n; 13 | int dim; 14 | double ans; 15 | bool cross(REG &x,REG &y) 16 | { 17 | for(int i=0;inext=tail; 29 | cur->pre=tail->pre; 30 | tail->pre->next=cur; 31 | tail->pre=cur; 32 | } 33 | void cut(REG x,REG y) 34 | { 35 | for(int i=0;ipre=tail->next=NULL; 61 | head->next=tail; 62 | tail->pre=head; 63 | } 64 | void solve() 65 | { 66 | for(int i=1;i<=n;++i) 67 | { 68 | cur=new REG; 69 | for(int j=0;jst[j]); 70 | for(int j=0;jed[j]); 71 | for(REG *q=head->next;q!=tail;q=q->next) 72 | { 73 | if(cross(*q,*cur)){ 74 | cut(*q,*cur); 75 | /* delete q */ 76 | q->pre->next=q->next; 77 | q->next->pre=q->pre; 78 | delete q; 79 | } 80 | } 81 | /* add cur before tail */ 82 | add(*cur); 83 | delete cur; 84 | } 85 | 86 | ans=0; 87 | for(REG *q=head->next;q!=tail;q=q->next) 88 | { 89 | cord_t sum=1; 90 | for(int i=0;ied[i]-q->st[i]); 92 | ans+=sum; 93 | } 94 | printf("Total explored area: %.2lf\n\n",ans); 95 | } 96 | void clear() 97 | { 98 | for(REG *q=head->next;q!=tail;q=q->next) 99 | delete q->pre; 100 | delete tail; 101 | } 102 | int main() 103 | { 104 | freopen("pku1151.in","r",stdin); 105 | dim=2;/* current dimension */ 106 | int cs=0; 107 | while(scanf("%d",&n),n) 108 | { 109 | printf("Test case #%d\n",++cs); 110 | init(); 111 | solve(); 112 | clear(); 113 | } 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /数据结构/pku1177求矩形并边长.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | struct INTERVAL{ 6 | int x,y1,y2,add; 7 | INTERVAL(int ix=0,int iy1=0,int iy2=0,int iadd=0): 8 | x(ix),y1(iy1),y2(iy2),add(iadd) {} 9 | }; 10 | struct NODE{ 11 | int c,line; 12 | bool lb,rb; 13 | }; 14 | NODE tr[1<<16]; 15 | INTERVAL reg[10010]; 16 | int cord[5010][4]; 17 | int n,my,ans; 18 | int ll,rr,add; 19 | void input() 20 | { 21 | scanf("%d",&n); 22 | my=-1; 23 | for(int i=0;ir || rr0) { //如果是直接覆盖,那么就按照题目意思来修改当前的值 38 | tr[x].c++; 39 | tr[x].line=1; 40 | tr[x].lb=tr[x].rb=1; 41 | } 42 | else{ 43 | tr[x].c--; 44 | if(tr[x].c==0) //如果覆盖都去掉那么就要恢复原来没覆盖时候 45 | //的状态,那就么这里就分叶子和非叶子的不同而不同修改 46 | { 47 | if(lmy) my=y1; 100 | if(y2>my) my=y2; 101 | reg[i]=INTERVAL(x1,y1,y2-1,1); 102 | reg[i+n]=INTERVAL(x2,y1,y2-1,-1); 103 | } 104 | work(); 105 | } 106 | int main() 107 | { 108 | freopen("pku1177.in","r",stdin); 109 | input(); 110 | ans=0; 111 | solve(); 112 | for(int i=0;i 2 | #include 3 | #define maxn 10010 4 | #define inf 1000000000 5 | using namespace std; 6 | int n; 7 | /*link*/ 8 | int dep[maxn],link_num[maxn]; 9 | int link_len[maxn]; 10 | int from[maxn];/*the direct father*/ 11 | int edge2point[maxn]; 12 | int fa[maxn]; 13 | int nlink; 14 | /*lca*/ 15 | int dfn[maxn*2]; 16 | int rmq[maxn*2][14]; 17 | int fst_pos[maxn]; 18 | int dfn_len; 19 | /*graph*/ 20 | struct edge{ 21 | int v,c,id,next; 22 | }e[maxn*2]; 23 | int val[maxn];/*value of the point*/ 24 | int ne; 25 | int beg[maxn]; 26 | /*segment tree*/ 27 | struct seg_node{ 28 | int max; 29 | seg_node *left,*right; 30 | }; 31 | seg_node *seg[maxn]; 32 | int ll,rr; 33 | // 34 | void add(int u,int v,int c,int id) 35 | { 36 | e[ne].v=v; 37 | e[ne].next=beg[u]; 38 | e[ne].c=c; 39 | e[ne].id=id; 40 | beg[u]=ne++; 41 | } 42 | void input() 43 | { 44 | int x,y,c; 45 | memset(beg,255,sizeof(beg)); 46 | ne=0; 47 | scanf("%d",&n); 48 | for(int i=1;imax_size) max_size=tmp,n_son=e[i].v; 70 | } 71 | if(n_son!=-1) fa[n_son]=x; 72 | return max_size+1; 73 | } 74 | void cal_rmq() 75 | { 76 | dfn_len=0; 77 | nlink=0; 78 | val[1]=0; 79 | dfs(1,-1,1); 80 | 81 | for(int i=0;ileft=tmp->right=NULL; 99 | tmp->max=-inf; 100 | return tmp; 101 | } 102 | int Max(seg_node *x,seg_node *y) 103 | { 104 | if(x==NULL) return y->max; 105 | if(y==NULL) return x->max; 106 | return x->max>y->max?x->max:y->max; 107 | } 108 | void change(seg_node *&x,int l,int r,int pos,int new_val) 109 | { 110 | if(x==NULL) x=get_segnode(); 111 | if(l==r){ 112 | x->max=new_val; 113 | }else { 114 | if(pos<=(l+r)/2) change(x->left,l,(l+r)/2,pos,new_val); 115 | else change(x->right,(l+r)/2+1,r,pos,new_val); 116 | x->max=Max(x->left,x->right); 117 | } 118 | } 119 | int find(seg_node *x,int l,int r) 120 | { 121 | if(rmax; 123 | int d1=find(x->left,l,(l+r)/2); 124 | int d2=find(x->right,(l+r)/2+1,r); 125 | return d1>d2?d1:d2; 126 | } 127 | void cal_link() 128 | { 129 | /*union set*/ 130 | for(int i=1;i<=n;++i) 131 | if(fa[i]!=i) fa[i]=find_head(i); 132 | /*label the link*/ 133 | int lab[maxn]; 134 | nlink=0; 135 | memset(lab,0,sizeof(lab)); 136 | memset(link_len,0,sizeof(link_len)); 137 | for(int i=1;i<=n;++i) 138 | if(fa[i]==i) lab[i]=++nlink; 139 | for(int i=1;i<=n;++i) 140 | link_num[i]=lab[fa[i]]; 141 | for(int i=1;i<=n;++i) 142 | link_len[link_num[i]]++; 143 | /*construct segment tree*/ 144 | memset(seg,0,sizeof(seg)); 145 | for(int i=1;i<=n;++i) 146 | change(seg[link_num[i]],1,link_len[link_num[i]],dep[i]-dep[fa[i]]+1,val[i]); 147 | } 148 | int lca(int x,int y) 149 | { 150 | int k; 151 | x=fst_pos[x]; 152 | y=fst_pos[y]; 153 | if(x>y) { x=x^y; y=x^y; x=x^y; } 154 | for(k=0;1<d2?d1:d2; 172 | } 173 | } 174 | void answer() 175 | { 176 | char task[20]; 177 | int x,y,z; 178 | int ans,tmp; 179 | while(scanf("%s",task),strcmp(task,"DONE")) 180 | { 181 | scanf("%d%d",&x,&y); 182 | if(task[0]=='C'){ 183 | x=edge2point[x]; 184 | change(seg[link_num[x]],1,link_len[link_num[x]],dep[x]-dep[fa[x]]+1,y); 185 | }else { 186 | if(x==y) { 187 | printf("0\n"); 188 | continue; 189 | } 190 | z=lca(x,y); 191 | ans=tmp=-inf; 192 | if(x!=z) ans=find_max(x,z); 193 | if(y!=z) tmp=find_max(y,z); 194 | if(tmp>ans) ans=tmp; 195 | printf("%d\n",ans); 196 | } 197 | } 198 | } 199 | void clear(seg_node *x) 200 | { 201 | if(x==NULL) return ; 202 | clear(x->left); 203 | clear(x->right); 204 | delete x; 205 | } 206 | void clear_segtree() 207 | { 208 | for(int i=1;i<=nlink;++i) 209 | clear(seg[i]); 210 | } 211 | int main() 212 | { 213 | freopen("s357.in","r",stdin); 214 | int cs; 215 | scanf("%d",&cs); 216 | while(cs--) 217 | { 218 | input(); 219 | cal_rmq(); 220 | cal_link(); 221 | answer(); 222 | clear_segtree(); 223 | } 224 | return 0; 225 | } 226 | -------------------------------------------------------------------------------- /数据结构/zju3512左偏树.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 左偏树,zju3512,关键操作是merge,所有其他操作都以其为核心。 3 | */ 4 | #include 5 | #include 6 | #include 7 | #define MAXN 50010 8 | 9 | using namespace std; 10 | typedef long long ll; 11 | struct node{ 12 | int left,right; 13 | int key; 14 | int dist; 15 | }; 16 | int n; 17 | node nd[MAXN]; 18 | int stk[MAXN]; 19 | int top; 20 | int q[MAXN],fa[MAXN]; 21 | ll ans; 22 | 23 | int myabs(int x) { return x<0? -x : x; } 24 | int merge(int a,int b) //合并堆 25 | { 26 | if(a == 0) return b; 27 | if(b == 0) return a; 28 | if (nd[a].key < nd[b].key) swap(a,b); 29 | nd[a].right = merge(nd[a].right, b); 30 | if(nd[nd[a].left].dist < nd[nd[a].right].dist) swap(nd[a].left, nd[a].right); 31 | nd[a].dist = nd[nd[a].right].dist + 1; 32 | return a; 33 | } 34 | void Delete(int x) 35 | { 36 | int q = fa[x]; 37 | int p = merge(nd[x].left, nd[x].right); 38 | fa[p] = q; 39 | if( q!=0 && nd[q].left == x) nd[q].left = p; 40 | if( q!=0 && nd[q].right == x) nd[q].right = p; 41 | while(q != NULL) { 42 | if(nd[nd[q].left].dist < nd[nd[q].right].dist) 43 | swap(nd[q].left, nd[q].right); 44 | if(nd[nd[q].right].dist + 1 == nd[q].dist ) break; 45 | nd[q].dist = nd[nd[q].right].dist + 1; 46 | q = fa[q]; 47 | } 48 | } 49 | int main() 50 | { 51 | while(scanf("%d",&n) , n) 52 | { 53 | q[0] = 0; 54 | top =0; 55 | for(int i=1; i<=n; i++) 56 | { 57 | scanf("%d", &nd[i].key); 58 | nd[i].left = nd[i].right = nd[i].dist=0; 59 | stk[++top] = i; 60 | q[top] = i; 61 | while(top > 1 && nd[stk[top-1]].key > nd[stk[top]].key) { 62 | stk[top-1] = merge(stk[top-1], stk[top]); 63 | top --; 64 | if (((q[top+1] - q[top])&1) && ((q[top] - q[top-1])&1)) { 65 | stk[top] = merge(nd[stk[top]].left, nd[stk[top]].right); 66 | } 67 | q[top ] = q[top+1]; 68 | } 69 | } 70 | 71 | ans = 0; 72 | for(int i=1; i<=top; i++) 73 | { 74 | for(int j=q[i-1]+1; j<=q[i]; j++) 75 | ans+=myabs(nd[j].key - nd[stk[i]].key); 76 | } 77 | printf("%lld\n",ans); 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /数据结构/树点剖分pku1741.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define N 100010 5 | #define M 200010 6 | #define INF 2000000000 7 | typedef long long LL; 8 | using namespace std; 9 | //QualityPoint 10 | struct NODE{ 11 | int v,d,next; 12 | }e[M]; 13 | int beg[N]; 14 | int nE; 15 | int p[N]; 16 | int FinMin,KeyPoint; 17 | int n,k; 18 | //divTree 19 | struct BEL{ 20 | int dep,bel; 21 | }b[N]; 22 | int nB; 23 | int sumBel[N],calBel[N]; 24 | LL ans; 25 | bool dead[N]; 26 | void add(int x,int y,int len) 27 | { 28 | nE++; 29 | e[nE].v=y; 30 | e[nE].next=beg[x]; 31 | e[nE].d=len; 32 | beg[x]=nE; 33 | } 34 | void input() 35 | { 36 | int u,v,l; 37 | memset(beg,0,sizeof(beg)); 38 | nE=0; 39 | for(int i=0;imax) max=p[e[i].v]; 63 | } 64 | if(max=0 && (LL)b[last].dep+b[i].dep>k) { 120 | sumBel[b[last].bel]--; 121 | last--; 122 | } 123 | ans=ans+last+1-sumBel[b[i].bel]; 124 | } 125 | dead[root]=true; 126 | for(int i=beg[root];i;i=e[i].next) 127 | if(e[i].v!=fa && !dead[e[i].v]) 128 | divTree(e[i].v,root); 129 | } 130 | void solve() 131 | { 132 | ans=0; 133 | memset(dead,0,sizeof(dead)); 134 | divTree(1,-1); 135 | printf("%lld\n",ans/2); 136 | } 137 | int main() 138 | { 139 | //freopen("snail.in","r",stdin); 140 | while(scanf("%d%d",&n,&k),n!=0 || k!=0) 141 | { 142 | input(); 143 | solve(); 144 | } 145 | return 0; 146 | } 147 | -------------------------------------------------------------------------------- /解方程/二进制高斯消元.cpp: -------------------------------------------------------------------------------- 1 | //Tykoy 2010 Awkward Lights 2 | //二进制的高斯消元,利用bitset优化 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | bitset<630> f[626],tm; 9 | int a[30][30]; 10 | int n,m,d,s; 11 | int ab(int x) {return x<0?-x:x; } 12 | void input() 13 | { 14 | s=n*m; 15 | for(int i=0;i 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | bitset<630> f[626],tm; 9 | int a[30][30]; 10 | int n,m,d,s; 11 | int ab(int x) {return x<0?-x:x; } 12 | void input() 13 | { 14 | s=n*m; 15 | for(int i=0;i 2 | #include 3 | #include 4 | #define MOD 7 5 | using namespace std; 6 | const char week[7][4]={"MON","TUE","WED","THU","FRI","SAT","SUN"}; 7 | int n,m; 8 | int a[310][310]; 9 | int x[310]; 10 | const int ni[7]={0,1,4,5,2,3,6}; 11 | int zero=0; 12 | void input() 13 | { 14 | int howMany,kind,nst,nen; 15 | char st[4],en[4]; 16 | memset(a,0,sizeof(a)); 17 | for(int i=0;i=n)break; 68 | else{ 69 | bool flag=false; 70 | for(int j=i;jzhi;--i) if(a[i][n]) return -1; //若zhi行之后的a[i][n]不是0,则显然无解。 89 | if(zhi=0;--i) 91 | { 92 | for(int j=i+1;j 2 | #include 3 | #include 4 | #include 5 | #define N 200010 6 | typedef long long ll; 7 | const ll inf=(ll)1000000001*1000000001; 8 | using namespace std; 9 | struct PPOINT{ 10 | int x,y; 11 | }; 12 | PPOINT P[N],Q[N],tm[N],tm2[N]; 13 | int n; 14 | ll d; 15 | void input() 16 | { 17 | scanf("%d",&n); 18 | for(int i=0;ir2) { dest[len++]=src[l1++];continue;} 32 | if(l1>r1) { dest[len++]=src[l2++];continue;} 33 | if(src[l1].y=0;--j) 67 | if(dob(tm[i].y-tm[j].y)>delta) break; else 68 | { 69 | if((d=::distance(tm[i],tm[j])) 2 | #include 3 | #define SETTING_OF_BASE 10000 //缩位 4 | 5 | #define LIM 100 //最大位数 6 | #define MAX(x,y) ((x)>(y)?(x):(y)); 7 | using namespace std; 8 | typedef long long LL; 9 | //********************************************************************** 10 | class BigNumber 11 | { 12 | public: 13 | int a[LIM]; 14 | static int BASE; 15 | public: 16 | //constructor 17 | BigNumber(); 18 | BigNumber(int); 19 | BigNumber(const BigNumber &); 20 | // 21 | BigNumber& operator=(const int); 22 | BigNumber& operator=(const BigNumber &); 23 | //comparision operations 24 | int cmp(const BigNumber &); 25 | bool operator>(const BigNumber &); 26 | bool operator<(const BigNumber &); 27 | bool operator==(const BigNumber &); 28 | bool operator>=(const BigNumber &); 29 | bool operator<=(const BigNumber &); 30 | //print function with a string at the end 31 | void print(const char *) const ; 32 | //operator on int 33 | void operator+=(int); 34 | void operator-=(int);//Assume the result is nonegative 35 | void operator*=(int); 36 | bool operator/=(int);//Return true if there's no remain.False wtherwise. 37 | //operator with BigNumber 38 | void operator+=(const BigNumber &); 39 | void operator-=(const BigNumber &); 40 | void operator*=(const BigNumber &); 41 | bool operator/=(const BigNumber &);//The same with operator on int. 42 | }; 43 | //********************************************************************** 44 | BigNumber::BigNumber() 45 | { 46 | memset(a,0,sizeof(a)); 47 | } 48 | BigNumber::BigNumber(int initVal) 49 | { 50 | memset(a,0,sizeof(a)); 51 | while(initVal>0) 52 | { 53 | a[++a[0]]=initVal%BASE; 54 | initVal/=BASE; 55 | } 56 | } 57 | BigNumber::BigNumber(const BigNumber &rhs) 58 | { 59 | memset(a,0,sizeof(a)); 60 | memcpy(a,rhs.a,sizeof(a)); 61 | } 62 | BigNumber& BigNumber::operator=(const int R) 63 | { 64 | *this=BigNumber(R); 65 | return *this; 66 | } 67 | BigNumber& BigNumber::operator=(const BigNumber &R) 68 | { 69 | memcpy(a,R.a,sizeof(int)*(R.a[0]+1)); 70 | return *this; 71 | } 72 | //********************************************************************** 73 | int BigNumber::BASE=SETTING_OF_BASE; 74 | //********************************************************************** 75 | int BigNumber::cmp(const BigNumber & that) 76 | { 77 | if(a[0]>that.a[0]) return 1; 78 | if(a[0]0 && a[i]==that.a[i]) --i; 81 | return a[i]-that.a[i]; 82 | } 83 | bool BigNumber::operator>(const BigNumber & that) 84 | { 85 | return cmp(that)>0; 86 | } 87 | bool BigNumber::operator<(const BigNumber & that) 88 | { 89 | return cmp(that)<0; 90 | } 91 | bool BigNumber::operator==(const BigNumber & that) 92 | { 93 | return cmp(that)==0; 94 | } 95 | bool BigNumber::operator>=(const BigNumber &that) 96 | { 97 | return cmp(that)>=0; 98 | } 99 | bool BigNumber::operator<=(const BigNumber &that ) 100 | { 101 | return cmp(that)<=0; 102 | } 103 | //********************************************************************** 104 | void BigNumber::operator+=(int add) 105 | { 106 | this->operator+=(BigNumber(add)); 107 | } 108 | void BigNumber::operator-=(int add) 109 | { 110 | this->operator-=(BigNumber(add)); 111 | } 112 | void BigNumber::operator*=(int mult) 113 | { 114 | this->operator*=(BigNumber(mult)); 115 | } 116 | bool BigNumber::operator/=(int dv) 117 | { 118 | LL tm=0; 119 | for(int i=a[0];i>0;--i) 120 | { 121 | tm=tm*BASE+a[i]; 122 | a[i]=tm/dv; 123 | tm%=dv; 124 | } 125 | while(a[0]>0 && a[a[0]]==0) --a[0]; 126 | 127 | if(tm!=0) return false; 128 | else return true; 129 | } 130 | //********************************************************************** 131 | void BigNumber::operator+=(const BigNumber &that) 132 | { 133 | int add=0,w=MAX(a[0],that.a[0]); 134 | for(int i=1;i<=w;++i) 135 | { 136 | a[i]+=that.a[i]+add; 137 | add=a[i]/BASE; 138 | a[i]%=BASE; 139 | if(i>that.a[0] && add==0) break; 140 | } 141 | a[0]=w; 142 | while(add) 143 | { 144 | a[++a[0]]=add%BASE; 145 | add/=BASE; 146 | } 147 | } 148 | void BigNumber::operator-=(const BigNumber &that) 149 | { 150 | for(int i=1,add=0;i<=a[0];++i) 151 | { 152 | a[i]-=(that.a[i]+add); 153 | add=0; 154 | if(a[i]<0) 155 | { 156 | a[i]+=BASE; 157 | add=1; 158 | } 159 | } 160 | while(a[0]>0 && !a[a[0]]) --a[0]; 161 | } 162 | void BigNumber::operator*=(const BigNumber &that) 163 | { 164 | int z[LIM]; 165 | int add=0,w=0; 166 | memset(z,0,sizeof(z)); 167 | for(int i=1;i<=a[0];++i) 168 | { 169 | for(int j=1;j<=that.a[0];++j) 170 | { 171 | z[i+j-1]+=a[i]*that.a[j]+add; 172 | add=z[i+j-1]/BASE; 173 | z[i+j-1]%=BASE; 174 | } 175 | w=i+that.a[0]-1; 176 | while(add) 177 | { 178 | w++; 179 | z[w]+=add; 180 | add=z[w]/BASE; 181 | z[w]%=BASE; 182 | } 183 | } 184 | z[0]=a[0]+that.a[0]; 185 | while(z[0]>0 && z[z[0]]==0) z[0]--; 186 | memset(a,0,sizeof(a)); 187 | memcpy(a,z,sizeof(int)*(z[0]+1)); 188 | } 189 | bool BigNumber::operator/=(const BigNumber &that) 190 | { 191 | if(this==&that) 192 | { 193 | *this=BigNumber(1); 194 | return true; 195 | } 196 | BigNumber l(0),r=*this; 197 | BigNumber mid,tm; 198 | while(l0;--i) 219 | printf("%04d",a[i]); 220 | printf("%s",str); 221 | } 222 | //********************************************************************** 223 | int main() 224 | { 225 | 226 | } 227 | -------------------------------------------------------------------------------- /高精度/fft.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #define MAXN 263010 7 | #define EPS 1e-8 8 | 9 | using namespace std; 10 | typedef complex cp; 11 | const double pi = acos(-1.0); 12 | 13 | char s1[MAXN],s2[MAXN]; 14 | cp x1[MAXN],x2[MAXN]; 15 | cp t1[MAXN],t2[MAXN]; 16 | cp x3[MAXN]; 17 | int ans[MAXN]; 18 | int n,m; 19 | 20 | void output(cp arr[], int len) 21 | { 22 | for(int i=0; i ", arr[i].real(), arr[i].imag()); 24 | printf("\n"); 25 | } 26 | void init_array(char *s, cp a[], int len, int retlen) //初始化IDF数组 27 | { 28 | for(int i=0; i>= 1; 39 | } 40 | return ret; 41 | } 42 | void bit_reverse_copy(cp in[], cp out[], int n, int bitnum) 43 | { 44 | for(int i=0; i0 && ans[n-1] == 0) n--; 83 | } 84 | int main() 85 | { 86 | while(scanf("%s%s", s1, s2) != EOF) 87 | { 88 | int l1 = strlen(s1), l2 = strlen(s2); 89 | m = l1 + l2; 90 | for(n =1; n=0; i--) 103 | printf("%d", ans[i]); 104 | printf("\n"); 105 | } 106 | } 107 | return 0; 108 | } 109 | --------------------------------------------------------------------------------