ACM常用模板整理
线段树单点修改区间查询
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=;
struct segmentTree{
int sum;
}tree[maxn<<];
int per[maxn];
void PushUp(int rt){
tree[rt].sum=tree[rt<<].sum+tree[rt<<|].sum;
}
void build(int l,int r,int rt){
if(l==r){
tree[rt].sum=per[l];
return;
}
int mid=(l+r)/;
build(lson);
build(rson);
PushUp(rt);
}
void update(int x,int add,int l,int r,int rt){
if(l==r){
tree[rt].sum+=add;
return;
}
int mid=(l+r)/;
if(x<=mid)update(x,add,lson);
else update(x,add,rson);
PushUp(rt);
}
int query(int a,int b,int l,int r,int rt){
if(a<=l&&b>=r){
return tree[rt].sum;
}
int ans=;
int mid=(l+r)/;
if(a<=mid) ans+=query(a,b,lson);
if(b>mid) ans+=query(a,b,rson);
return ans;
}
int main(){
int t,n,cas=;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
printf("Case %d:\n",cas++);
for(int i=;i<=n;i++){
scanf("%d",&per[i]);
}
build(,n,);
char op[];
while(scanf("%s",op)!=EOF){
if(strcmp(op,"End")==)break;
if(strcmp(op,"Query")==){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",query(a,b,,n,));
}
else if(strcmp(op,"Add")==){
int a,b;
scanf("%d%d",&a,&b);
update(a,b,,n,);
}
else if(strcmp(op,"Sub")==){
int a,b;
scanf("%d%d",&a,&b);
update(a,-b,,n,);
}
}
}
return ;
}
线段树同时维护和、最大值、最小值
#include <cstdio>
#include <cstring> #define maxn 100000 + 10
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1 int min(int a, int b) {return a<b ? a : b;}
int max(int a, int b) {return a>b ? a : b;} struct Node
{
int sum, Min, Max, lazy;
} T[maxn<<]; void PushUp(int rt)
{
T[rt].sum = T[rt<<].sum + T[rt<<|].sum;
T[rt].Min = min(T[rt<<].Min, T[rt<<|].Min);
T[rt].Max = max(T[rt<<].Max, T[rt<<|].Max);
} void PushDown(int L, int R, int rt)
{
int mid = (L + R) >> ;
int t = T[rt].lazy;
T[rt<<].sum = t * (mid - L + );
T[rt<<|].sum = t * (R - mid);
T[rt<<].Min = T[rt<<|].Min = t;
T[rt<<].Max = T[rt<<|].Max = t;
T[rt<<].lazy = T[rt<<|].lazy = t;
T[rt].lazy = ;
} void Build(int L, int R, int rt)
{
if(L == R)
{
scanf("%d", &T[rt].sum);
T[rt].Min = T[rt].Max = T[rt].sum;
return ;
}
int mid = (L + R) >> ;
Build(Lson);
Build(Rson);
PushUp(rt);
} void Update(int l, int r, int v, int L, int R, int rt)
{
if(l==L && r==R)//修改区间值
{
T[rt].lazy = v;
T[rt].sum = v * (R - L + );
T[rt].Min = T[rt].Max = v;
return ;
}
int mid = (L + R) >> ;
if(T[rt].lazy) PushDown(L, R, rt);//向下更新一级
if(r <= mid) Update(l, r, v, Lson);
else if(l > mid) Update(l, r, v, Rson);
else
{
Update(l, mid, v, Lson);
Update(mid+, r, v, Rson);
}
PushUp(rt);
} int Query(int l, int r, int L, int R, int rt)
{
if(l==L && r== R)
{
printf("(%d, %d)---Min: %d Max: %d Sum: %d \n", L, R, T[rt].Min, T[rt].Max, T[rt].sum);
return T[rt].sum;
}
int mid = (L + R) >> ;
if(T[rt].lazy) PushDown(L, R, rt);
if(r <= mid) return Query(l, r, Lson);
else if(l > mid) return Query(l, r, Rson);
return Query(l, mid, Lson) + Query(mid + , r, Rson);
} int main()
{
int n, q;
scanf("%d", &n);
Build(, n, );
scanf("%d", &q);
int a, b, c, d;
while(q--)
{
scanf("%d%d%d", &a, &b, &c);
if(a)
{
scanf("%d", &d);
Update(b, c, d, , n, );
}
else printf("%d\n", Query(b, c, , n, ));
}
return ;
}
线段树区间取模(平方)区间查询
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=;
struct segmentTree{
int sum,maxnum,col;
}tree[maxn<<];
int per[maxn],n,m;
inline void PushUp(int rt){
tree[rt].sum=tree[rt<<].sum+tree[rt<<|].sum;
tree[rt].maxnum=max(tree[rt<<].maxnum,tree[rt<<|].maxnum);
}
void build(int l,int r,int rt){
tree[rt].col=;
if(l==r){
tree[rt].sum=per[l];
tree[rt].maxnum=per[l];
return;
}
int mid=(l+r)>>;
build(lson);
build(rson);
PushUp(rt);
}
void update(int x,int add,int l,int r,int rt){
if(l==r){
tree[rt].sum=add;
tree[rt].maxnum=add;
return;
}
int mid=(l+r)>>;
if(x<=mid)update(x,add,lson);
else update(x,add,rson);
PushUp(rt);
}
void update2(int x,int mod,int l,int r,int rt){
if (tree[rt].maxnum<mod) return;
if(l==r){
tree[rt].sum=tree[rt].sum%mod;
tree[rt].maxnum=tree[rt].maxnum%mod;
return;
}
int mid=(l+r)>>;
if(x<=mid)update2(x,mod,lson);
else update2(x,mod,rson);
PushUp(rt);
}
int query(int a,int b,int l,int r,int rt){
if(a<=l&&b>=r){
return tree[rt].sum;
}
int ans=;
int mid=(l+r)>>;
if(a<=mid) ans+=query(a,b,lson);
if(b>mid) ans+=query(a,b,rson);
return ans;
}
void mod(int l,int r,int rt,int a,int b,int m)
{if (tree[rt].maxnum<m) return;
if (a<=l&&r<=b)
{if (l==r)
{tree[rt].sum%=m;
tree[rt].maxnum=tree[rt].sum;
return;
}
int mid=(l+r)>>;
if (a<=mid) mod(lson,a,b,m);
if (b>mid) mod(rson,a,b,m);
PushUp(rt);
return;
}
int mid=(l+r)>>;
if (a<=mid) mod(lson,a,b,m);
if (b>mid) mod(rson,a,b,m);
PushUp(rt);
}
int main()
{while (scanf("%d%d",&n,&m)!=EOF)
{int i;
for (i=;i<=n;i++) scanf("%d",&per[i]);
build(,n,);
for (i=;i<=m;i++)
{int op;
scanf("%d",&op);
if (op==)
{int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r,,n,));
} else
if (op==)
{int l,r,x;
scanf("%d%d%d",&l,&r,&x);
mod(,n,,l,r,x);
} else
if (op==)
{int k,x;
scanf("%d%d",&k,&x);
update(k,x,,n,);
}
}
}
return ;
}
最短路spfa
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;
const int maxn=;
const int inf =0x7ffffff;
struct edge
{
int from,to,w,next;
}e[];
int head[maxn];
int vis[maxn];
int dist[maxn];
int n,m,t;
void add(int i,int j,int w)
{
e[t].from=i;
e[t].to=j;
e[t].w=w;
e[t].next=head[i];
head[i]=t++;
}
void spfa(int s)
{
queue <int> q;
for(int i=;i<=n;i++)
dist[i]=inf;
memset(vis,false,sizeof(vis));
q.push(s);
dist[s]=;
//cout<<q.empty()<<endl;
while(!q.empty())
{ int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-;i=e[i].next)
{ //cout<<i<<endl;
//system("pause");
int v=e[i].to;
if(dist[v]>dist[u]+e[i].w)
{
dist[v]=dist[u]+e[i].w;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
}
void doing()
{scanf("%d%d",&n,&m);
t=;
memset(head,-,sizeof(head));
int i;
for (i=;i<=m;i++)
{int x,y;
scanf("%d%d",&x,&y);
add(x,y,);
add(y,x,);
}
for (i=;i<=n;i++)
{int x;
scanf("%d",&x);
if (x!=-)
add(i,x,);
}
spfa();
if (dist[n]==inf) printf("-1\n"); else
printf("%d\n",dist[n]);
}
int main()
{int T;
scanf("%d",&T);
int i;
for (i=;i<=T;i++)
{printf("Case #%d: ",i);
doing();
}
return ;
}
2-SAT稳定党员
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#define eps 1e-5
using namespace std;
const int MAXN = ;
const int MAXM = ;
struct Edge
{
int to;
int next;
} edge[MAXM];
int head[MAXN],tot; void init()
{
tot = ;
memset(head,-,sizeof(head));
}
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
bool vis[MAXN];
int S[MAXN], top; bool dfs(int u)
{
if(vis[u^])
return false;
if(vis[u])
return true;
vis[u] = true;
S[top++] = u;
for(int i = head[u]; i != -; i = edge[i].next)
{
if(!dfs(edge[i].to))
return false;
}
return true;
} bool Twosat(int n)
{
memset(vis,false,sizeof(vis));
for(int i = ; i < n; i += )
{
if(vis[i] || vis[i^])continue;
top = ;
if(!dfs(i))
{
while(top)
{
vis[S[--top]] = false;
}
if(!dfs(i^))
return false;
}
}
return true;
} int main()
{
int n, m;
int u, v;
while(~scanf("%d%d",&n,&m))
{
init();
while(m--)
{
scanf("%d%d",&u,&v);
u--;
v--;
addedge(u,v^);
addedge(v,u^);
}
if(Twosat(*n))
{
for(int i = ; i < *n; i++)
{
if(vis[i])
{
printf("%d\n",i+);
}
}
}
else
printf("NIE\n");
}
return ;
}
欧几里得与扩展欧几里得
long long GCD(long long a,long long b)
{
if(b == )
return a;
else
return GCD(b,a%b);
} void ExGCD(long long a,long long b,long long &d,long long &x,long long &y)
{
if( !b )
{
x = ;
y = ;
d = a;
}
else
{
ExGCD(b,a%b,d,y,x);
y -= x * (a/b);
}
}
中国剩余定理
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;
int main()
{int p,e,i,d,n;
int num=;
int tot;
scanf("%d",&tot);
int t;
for (t=;t<=tot;t++)
{while (true)
{scanf("%d%d%d%d",&p,&e,&i,&d);
if (p!=-)
{n=(*p+*e+*i-d)%;
if (n<=) n+=;
printf("Case %d: the next triple peak occurs in %d days.\n",num++,n);
}
else break;
}
}
return ;
}
字典树
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
using namespace std;
char c[];
int t=;
struct ss
{int num;
ss *a[];
};
ss *root,memory[];
string s;
ss *create()
{ss *p=&memory[t++];
int i;
for (i=;i<;i++)
p->a[i]=NULL;
p->num=;
return p;
}
void insert()
{int i,len=s.size();
ss *tt,*p=root;
for (i=;i<len;i++)
{int pos=s[i]-'a';
if (p->a[pos]==NULL)
{tt=create();
p->a[pos]=tt;
}
p=p->a[pos];
p->num++;
}
}
void search()
{int i,len=s.size();
ss *p=root;
for (i=;i<len;i++)
{char pos=s[i]-'a';
if (p->a[pos]==NULL)
{puts("");
return;
}
p=p->a[pos];
}
printf("%d\n",p->num);
}
int main()
{gets(c);
root=create();
while (strlen(c)!=)
{s.assign(c);
insert();
gets(c);
}
while (scanf("%s\n",&c)!=EOF)
{s.assign(c);
search();
}
return ;
匈牙利算法
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<queue>
using namespace std;
int map[][],visit[],match[];
int n,m,k;
struct node
{
int x,y;
}rc[*];
bool DFS(int k)
{
for(int i=;i<=m;i++)
{
if(visit[i]||!map[k][i])
continue;
visit[i]=;
if(!match[i]||DFS(match[i]))
{
match[i]=k;
return true;
} }
return false;
}
int Match()
{
memset(match,,sizeof(match));
int cnt=;
for(int i=;i<=n;i++)
{
memset(visit,,sizeof(visit));
if(DFS(i)) cnt++;
}
return cnt;
}
int main()
{
int i,t=;
while(scanf("%d %d %d",&n,&m,&k)!=EOF)
{
memset(map,,sizeof(map));
for(i=;i<=k;i++)
{
scanf("%d %d",&rc[i].x,&rc[i].y);
map[rc[i].x][rc[i].y]=; }
int num=,ans;
ans=Match();
for(i=;i<=k;i++)
{
map[rc[i].x][rc[i].y]=;
if(ans>Match()) num++;
map[rc[i].x][rc[i].y]=;
}
printf("Board %d have %d important blanks for %d chessmen.\n",t++,num,ans);
}
return ;
}
LCA Tarjan算法
#include <iostream> #include <vector> #include <cstdio> #include <cstring> using namespace std; #define MAXN 1001 int fa[MAXN]; int ques[MAXN][MAXN]; int ind[MAXN]; bool vis[MAXN]; int cnt[MAXN]; vector<int>edge[MAXN]; int n,m; int find_father(int k) { if(fa[k] == k)return k; else return fa[k] = find_father(fa[k]); } void tarjan(int x){ for (int i=; i<=n; i++) { if (vis[i] && ques[x][i]) cnt[find_father(i)] += ques[x][i]; } fa[x] = x; vis[x] = true; for (int i=; i<edge[x].size(); i++) { tarjan(edge[x][i]); fa[edge[x][i]] = x; } } int main() { while (~scanf("%d", &n)) { for (int i=; i<=n; i++) { edge[i].clear(); } memset(ques, , sizeof(ques)); memset(vis, false, sizeof(vis)); memset(cnt, , sizeof(cnt)); memset(ind, , sizeof(ind)); int a, b; for (int i=; i<n; i++) { scanf("%d:(%d)", &a, &m); for (int j=; j<m; j++) { scanf(" %d", &b); edge[a].push_back(b); ind[b]++; } } scanf("%d", &m); for (int i=; i<m; i++) { scanf(" (%d %d)", &a, &b); ques[a][b]++; ques[b][a]++; } for (int i=; i<=n; i++) if (!ind[i]) { tarjan(i); break; } for (int i=; i<=n; i++) if (cnt[i]) printf("%d:%d\n", i, cnt[i]); } return ; }
Tarjan强连通分量
#define M 5010//题目中可能的最大点数 int STACK[M],top=;//Tarjan算法中的栈 bool InStack[M];//检查是否在栈中 int DFN[M];//深度优先搜索访问次序 int Low[M];//能追溯到的最早的次序 int ComponentNumber=;//有向图强连通分量个数 int Index=;//索引号 vector<int> Edge[M];//邻接表表示 vector<int> Component[M];//获得强连通分量结果 int InComponent[M];//记录每个点在第几号强连通分量里 int ComponentDegree[M];//记录每个强连通分量的度 void Tarjan(int i) { int j; DFN[i]=Low[i]=Index++; InStack[i]=true;STACK[++top]=i; for (int e=;e<Edge[i].size();e++) { j=Edge[i][e]; if (DFN[j]==-) { Tarjan(j); Low[i]=min(Low[i],Low[j]); } else if (InStack[j]) Low[i]=min(Low[i],Low[j]); } if (DFN[i]==Low[i]) { ComponentNumber++; do{ j=STACK[top--]; InStack[j]=false; Component[ComponentNumber]. push_back(j); InComponent[j]=ComponentNumber; } while (j!=i); } }
KMP算法
void kmp_pre(char x[], int m){
int i,j;
j = Next[] = -;
i = ;
while(i < m){
while(-!=j && x[i] != x[j]) j = Next[j];
Next[++i] = ++j;
}
}
int an[MAXN]; int tot;
int KMP_Count(char x[], int m, char y[], int n){
int i,j;
int ans = ;
kmp_pre(x,m);
i=j=;
while(i<n){
while(-!=j && y[i]!=x[j]) j = Next[j];
i++; j++;
if(j >= m){
ans ++; an[tot++] = i;
j = Next[j];
}
}
return ans;
} void kmp_pre(int x[], int m){
int i,j;
j = Next[] = -;
i = ;
while(i < m){
while(-!=j && x[i] != x[j]) j = Next[j];
Next[++i] = ++j;
}
}
int an[]; int tot;
int KMP_Count(int x[], int m, int y[], int n){
int i,j;
kmp_pre(x,m);
i=;
j=;
while(i<n){
while(-!=j && y[i]!=x[j]) j = Next[j];
i++; j++;
if(j >= m){
return i-m+;
}
}
return -;
}
扩展KMP(最长公共前缀)
void GetNext(char *T)
{
int a=;
int Tlen=strlen(T);
next[]=Tlen;
while(a<Tlen-&&T[a]==T[a+]) a++;
next[]=a;
a=;
for(int k=;k<Tlen;k++)
{
int p=a+next[a]-,L=next[k-a];
if((k-)+L>=p)
{
int j=(p-k+)>? p-k+:;
while(k+j<Tlen&&T[k+j]==T[j]) j++;
next[k]=j;
a=k;
}
else next[k]=L;
}
} void GetExtend(char *S,char *T)
{
int a=;
GetNext(T);
int Slen=strlen(S);
int Tlen=strlen(T);
int MinLen=Slen<Tlen? Slen:Tlen;
while(a<MinLen&&S[a]==T[a]) a++;
extend[]=a;
a=;
for(int k=;k<Slen;k++)
{
int p=a+extend[a]-,L=next[k-a];
if((k-)+L>=p)
{
int j=(p-k+)>? p-k+:;
while(k+j<Slen&&j<Tlen&&S[k+j]==T[j]) j++;
extend[k]=j;
a=k;
}
else extend[k]=L;
}
}
数位DP
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<iostream>
using namespace std;
const int N = ;
typedef long long LL;
int dig[N];
LL dp[N][][]; LL dfs(int pos,int pre,int istrue,int limit) {
if (pos < ) return istrue;
if (!limit && dp[pos][pre][istrue] != -)
return dp[pos][pre][istrue];
int last = limit ? dig[pos] : ;
LL ret = ;
for (int i = ; i <= last; i++) {
ret += dfs(pos-,i,istrue || (pre == && i == ),limit && (i == last));
}
if (!limit) {
dp[pos][pre][istrue] = ret;
}
return ret;
}
LL solve(LL n) {
int len = ;
while (n) {
dig[len++] = n % ;
n /= ;
}
return dfs(len-,,,);
}
int main(){
memset(dp,-,sizeof(dp));
int T; scanf("%d",&T);
while (T--) {
LL n;
cin>>n;
cout<<solve(n)<<endl;
}
return ;
}
组合数取模lucas
typedef long long LL;
using namespace std; LL exp_mod(LL a, LL b, LL p) {
LL res = ;
while(b != ) {
if(b&) res = (res * a) % p;
a = (a*a) % p;
b >>= ;
}
return res;
} LL Comb(LL a, LL b, LL p) {
if(a < b) return ;
if(a == b) return ;
if(b > a - b) b = a - b; LL ans = , ca = , cb = ;
for(LL i = ; i < b; ++i) {
ca = (ca * (a - i))%p;
cb = (cb * (b - i))%p;
}
ans = (ca*exp_mod(cb, p - , p)) % p;
return ans;
} LL Lucas(int n, int m, int p) {
LL ans = ; while(n&&m&&ans) {
ans = (ans*Comb(n%p, m%p, p)) % p;
n /= p;
m /= p;
}
return ans;
} int main() {
Read();
int n, m, p;
while(~scanf("%d%d%d", &n, &m, &p)) {
printf("%lld\n", Lucas(n, m, p));
}
return ;
}
block分块
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
using namespace std;
int n,k,a[],m,tot,sum[],ans[],pos[];
struct ss
{
int l,r,id,flag;
};
ss q[];
void add(int l,int r,int id,int flag)
{
q[++tot].l=l;
q[tot].r=r;
q[tot].id=id;
q[tot].flag=flag;
}
inline bool cmp(ss a,ss b)
{
if (pos[a.l]==pos[b.l]) return a.r<b.r;
return a.l<b.l;
}
int main()
{
while (scanf("%d",&n)!=EOF)
{
scanf("%d",&k);
int i;
for (i=;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&m);
tot=;
for (i=;i<=m;i++)
{
int l,r,u,v;
scanf("%d%d%d%d",&l,&r,&u,&v);
add(l,v,i,);
add(l,u-,i,-);
add(r+,v,i,-);
add(r+,u-,i,);
}
int block=(int)sqrt(n);
for (i=;i<=n;i++) pos[i]=(int)(i-)/block+;
sort(q+,q+tot+,cmp);
int l=,r=,tot2=;
memset(sum,,sizeof(sum));
//cout<<tot<<endl;
memset(ans,,sizeof(ans));
for (i=;i<=tot;i++)
{
while (l<q[i].l)
{
sum[a[l]]--;
tot2-=sum[k-a[l]];
l++;
}
while (l>q[i].l)
{
l--;
tot2+=sum[k-a[l]];
sum[a[l]]++;
}
while (r<q[i].r)
{
r++;
tot2+=sum[k-a[r]];
sum[a[r]]++;
}
while (r>q[i].r)
{
sum[a[r]]--;
tot2-=sum[k-a[r]];
r--;
}
//cout<<tot2<<endl;
ans[q[i].id]+=q[i].flag*tot2;
}
for (i=;i<=m;i++) printf("%d\n",ans[i]);
}
return ;
}
Heap
struct node
{
int64 id,x;
};
struct cmp
{
bool operator()(const node &a,const node &b)
{
return a.x>b.x;
}
};
priority_queue<node,vector<node>,cmp> q;
Set
struct Node{
int id; int num;
Node(int a, int b):id(a), num(b){}
bool operator == (const Node& T) const{
return id==T.id && num == T.num;
}
bool operator <(const Node& T) const{
if(num != T.num) return num > T.num;
else return id < T.id;
}
};
set<Node> st;
set<Node> ::iterator it;
st.insert(Node(i,po[i]));
离散化
void prepare(int *x) {
fo(i,,n) data[i]=x[i];
sort(data+,data+n+);
int m=unique(data+,data+n+)-data-;
fo(i,,n) x[i]=lower_bound(data+,data+m+,x[i])-data;
}
最小费用最大流
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to, next, cap, flow, cost;
int x, y;
} edge[MAXM],HH[MAXN],MM[MAXN];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N, M,n,m;
char map[MAXN][MAXN];
void init()
{
N = MAXN;
tol = ;
memset(head, -, sizeof(head));
}
void add(int u, int v, int cap, int cost)//左端点,右端点,容量,花费
{
edge[tol]. to = v;
edge[tol]. cap = cap;
edge[tol]. cost = cost;
edge[tol]. flow = ;
edge[tol]. next = head[u];
head[u] = tol++;
edge[tol]. to = u;
edge[tol]. cap = ;
edge[tol]. cost = -cost;
edge[tol]. flow = ;
edge[tol]. next = head[v];
head[v] = tol++;
}
bool spfa(int s, int t)
{
queue<int>q;
for(int i = ; i < N; i++)
{
dis[i] = INF;
vis[i] = false;
pre[i] = -;
}
dis[s] = ;
vis[s] = true;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i != -; i = edge[i]. next)
{
int v = edge[i]. to;
if(edge[i]. cap > edge[i]. flow &&
dis[v] > dis[u] + edge[i]. cost )
{
dis[v] = dis[u] + edge[i]. cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -) return false;
else return true;
}
//返回的是最大流, cost存的是最小费用
int minCostMaxflow(int s, int t, int &cost)
{
int flow = ;
cost = ;
while(spfa(s,t))
{
int Min = INF;
for(int i = pre[t]; i != -; i = pre[edge[i^]. to])
{
if(Min > edge[i]. cap - edge[i]. flow)
Min = edge[i]. cap - edge[i]. flow;
}
for(int i = pre[t]; i != -; i = pre[edge[i^]. to])
{
edge[i]. flow += Min;
edge[i^]. flow -= Min;
cost += edge[i]. cost * Min;
}
flow += Min;
}
return flow;
}
最大流EK
#define MAXN 500 #define MAXE 1100000 #define INF 0x7fffffff int net[MAXN],size;//邻接表部分 struct EDGE{ int v,next; int cap;//容量 }edge[MAXE]; void init(){ size=; memset(net,-,sizeof(net)); } void add(int u,int v,int cap){//加边 edge[size].v=v; edge[size].cap=cap; edge[size].next=net[u]; net[u]=size++; edge[size].v=u; edge[size].cap=; edge[size].next=net[v]; net[v]=size++; } int pe[MAXN];//记录当前点是由那条边转移过来的 int pre[MAXN];//记录前驱 queue<int> q;//BFS所用队列 int EK(int s,int t){ int max_flow=; while(true){//不停的找增广路 并进行增广 直到找不到增广路为止 while(!q.empty()) q.pop(); memset(pre,-,sizeof(pre)); q.push(s); while(!q.empty()){//BFS int u=q.front(); q.pop(); for(int i=net[u];i!=-;i=edge[i].next){ int v=edge[i].v; if(pre[v]==-&&edge[i].cap>){ q.push(v); pre[v]=u; pe[v]=i; } } if(pre[t]!=-) break;//到达汇点 找到一条增广路 跳出BFS } if(pre[t]==-) break;//没有找到增广路 跳出大循环 int aug=INF; for(int v=t;v!=s;v=pre[v]){//找到最小的容量 aug aug=min(aug,edge[pe[v]].cap); } for(int v=t;v!=s;v=pre[v]){ edge[pe[v]].cap-=aug;//减去aug edge[pe[v]^].cap+=aug;//反向边加上aug } max_flow+=aug; } return max_flow; }
最大流ISAP
#define MAXN 500 #define MAXE 1100000 #define INF 0x7fffffff int ne,nv,s,t; int size,net[MAXN]; struct EDGE{ int v,next; int cap; int flow; }edge[MAXE]; void init(){ size=; memset(net,-,sizeof(net)); } void add(int u,int v,int cap){ edge[size].v = v; edge[size].cap = cap; edge[size].flow = ; edge[size].next = net[u]; net[u] = size; ++size; edge[size].v = u; edge[size].cap = ; edge[size].flow = ; edge[size].next = net[v]; net[v] = size; ++size; } int gap[MAXN];//gap优化 int dist[MAXN];//距离标号 int pre[MAXN];//前驱 int curedge[MAXN];//当前弧 int ISAP(){ int cur_flow,u,temp,neck,i; int max_flow; memset(gap,,sizeof(gap)); memset(pre,-,sizeof(pre)); memset(dist,,sizeof(dist)); for(i=;i<=nv;i++) curedge[i]=net[i];//将当前弧初始话成邻接表的第一条边 gap[nv]=nv; max_flow=; u=s; while(dist[s]<nv){ if(u==t){//找到一条增广路 cur_flow=INF; for(i=s;i!=t;i=edge[curedge[i]].v){//沿着增广路找到最小增广流量 if(cur_flow>edge[curedge[i]].cap){ neck=i; cur_flow=edge[curedge[i]].cap; } } for(i=s;i!=t;i=edge[curedge[i]].v){//更新 temp=curedge[i]; edge[temp].cap-=cur_flow; edge[temp].flow+=cur_flow; temp^=; edge[temp].cap+=cur_flow; edge[temp].flow-=cur_flow; } max_flow+=cur_flow; u=neck;//下次直接从关键边的u开始新一轮的增广 } for(i=curedge[u];i!=-;i=edge[i].next)//找到一条允许弧 if(edge[i].cap>&&dist[u]==dist[edge[i].v]+) break; if(i!=-){//如果找到 将u指向v curedge[u]=i; pre[edge[i].v]=u; u=edge[i].v; } else{//找不到 if(==--gap[dist[u]]) break;//出现断层 curedge[u] = net[u];//把当前弧重新设为邻接表中满足要求的第一条弧 for(temp=nv,i=net[u];i!=-;i=edge[i].next) if(edge[i].cap > ) temp=temp<dist[edge[i].v]?temp:dist[edge[i].v]; dist[u]=temp+;//将这个点的距离标号设为由它出发的所有弧的终点的距离标号的最小值加1 ++gap[dist[u]]; if(u!=s)u=pre[u]; } } return max_flow; }
最大流MCMF
#define INF 0x7fffffff #define MAXN 1100 #define MAXE 1100000 int net[MAXN],size; struct EDGE{ int v,next; int cap; int cost; }edge[MAXE]; void init(){ size=; memset(net,-,sizeof(net)); } void add(int u,int v,int cap,int cost){ edge[size].v=v; edge[size].cap=cap; edge[size].cost=cost; edge[size].next=net[u]; net[u]=size++; edge[size].v=u; edge[size].cap=; edge[size].cost=-cost; edge[size].next=net[v]; net[v]=size++; } int nv;//点数 int dist[MAXN]; int pre[MAXN]; int pe[MAXN]; bool hash[MAXN]; queue<int>q; bool spfa(int s,int t){ while(!q.empty()) q.pop(); memset(hash,,sizeof(hash)); memset(pre,-,sizeof(pre)); for(int i=;i<=nv;i++) dist[i]=INF; dist[s]=; hash[s]=; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); hash[u]=; for(int i=net[u];i!=-;i=edge[i].next){ int v=edge[i].v; if(edge[i].cap&&dist[v]>dist[u]+edge[i].cost){ dist[v]=dist[u]+edge[i].cost; pre[v]=u; pe[v]=i; if(hash[v]==){ hash[v]=; q.push(v); } } } } if(pre[t]==-) return false; return true; } int MCMF(int s,int t,int need=){ int max_flow=; int min_cost=; while(spfa(s,t)){ int aug=INF; for(int v=t;v!=s;v=pre[v]){ aug=min(aug,edge[pe[v]].cap); } max_flow+=aug; min_cost+=dist[t]*aug; for(int v=t;v!=s;v=pre[v]){ edge[pe[v]].cap-=aug; edge[pe[v]^].cap+=aug; } } if(max_flow<need) return -; return min_cost; }
线段树区间合并
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#define maxn 100001
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
int sum[maxn<<],lsum[maxn<<],rsum[maxn<<],n,m,lazy[maxn<<];
void PushUp(int rt,int k)
{
lsum[rt]=lsum[rt<<];
rsum[rt]=rsum[rt<<|];
if (lsum[rt]==k-(k>>)) lsum[rt]+=lsum[rt<<|];
if (rsum[rt]==k>>) rsum[rt]+=rsum[rt<<];
sum[rt]=max(rsum[rt<<]+lsum[rt<<|],max(sum[rt<<],sum[rt<<|]));
}
void PushDown(int rt,int k)
{
if (lazy[rt]!=-)
{
lazy[rt<<]=lazy[rt<<|]=lazy[rt];
lsum[rt<<]=rsum[rt<<]=sum[rt<<]=lazy[rt]?:(k-(k>>));
lsum[rt<<|]=rsum[rt<<|]=sum[rt<<|]=lazy[rt]?:(k>>);
lazy[rt]=-;
}
}
void build(int l,int r,int rt)
{
lsum[rt]=rsum[rt]=sum[rt]=r-l+;
lazy[rt]=-;
if (l==r) return;
int mid=(l+r)>>;
build(lson);
build(rson);
}
int query(int w,int l,int r,int rt)
{
if (l==r) return l;
PushDown(rt,r-l+);
int mid=(l+r)>>;
if (sum[rt<<]>=w) return query(w,lson);
else if (rsum[rt<<]+lsum[rt<<|]>=w) return mid-rsum[rt<<]+;
else return query(w,rson);
}
void upd(int L,int R,int c,int l,int r,int rt)
{
//cout<<l<<" "<<r<<" "<<rt<<endl;
if (L<=l&&r<=R)
{
lsum[rt]=rsum[rt]=sum[rt]=c?:r-l+;
lazy[rt]=c;
return;
}
PushDown(rt,r-l+);
int mid=(l+r)>>;
if (L<=mid) upd(L,R,c,lson);
if (R>mid) upd(L,R,c,rson);
PushUp(rt,r-l+);
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
build(,n,);
while (m--)
{
int id;
scanf("%d",&id);
if (id==)
{
int a;
scanf("%d",&a);
if (sum[]<a) puts(""); else
{
int pos=query(a,,n,);
printf("%d\n",pos);
upd(pos,pos+a-,,,n,);
}
} else
{
int a,b;
scanf("%d%d",&a,&b);
upd(a,a+b-,,,n,);
}
}
}
return ;
}
求反素数
void dfs(int kk,long long num,long long sum,long long limit)
{
if (sum>k) return ;
if (sum==k) ans=min(ans,num);
for (int i=;i<=limit;i++) {
if (ans/p[kk] <num || sum*(i+)>k) break;
num*=p[kk];
if (k%(sum*(i+))==)
dfs(kk+,num,sum*(i+),i);
}
}
计算行列式
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#define LL long long
using namespace std;
LL n,m,A[][],p[],pos,d[],r[],len,B[][];
bool vd[]={};
void prime()
{
pos=;
for(int i=;i<;i++)
{
if(!vd[i])
{
if(i>) p[pos++]=i;
for(int j=(i<<);j<;j+=i)
vd[i]=;
}
}
}
void deal(LL k)
{
len=;
for(int i=;i<pos&&k!=;i++)
{
if(k%p[i]==)
{
while(k%p[i]==)
{
d[len++]=p[i];
k/=p[i];
}
}
}
}
LL exp(LL a,LL b,LL mod)
{
LL ans=;
while(b)
{
if(b&)ans=ans*a%mod;
a=a*a%mod;b>>=;
}
return ans;
}
void ex_gcd(LL a,LL b,LL &dd,LL &x,LL &y)
{
if(b==)
x=,y=,dd=a;
else
{
ex_gcd(b,a%b,dd,y,x);
y-=x*(a/b);
}
}
LL gauss(LL mod)
{
bool flag=;
LL ans=;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
B[i][j]=A[i][j];
for(int k=;k<n-;k++)
{
LL max_b=B[k][k];int bin=k;
for(int i=k+;i<n;i++)
if(B[i][k]>max_b)
max_b=B[i][k],bin=i;
if(bin!=k)
{
for(int i=k;i<n;i++)
swap(B[bin][i],B[k][i]);
flag^=;
}
if(B[k][k]<)B[k][k]+=mod;
LL Ni,y,dd;
ex_gcd(B[k][k],mod,dd,Ni,y);
Ni%=mod;
if(Ni<)Ni+=mod;
for(int j=k+;j<n;j++)
{
B[k][j]=B[k][j]*Ni%mod;
if(B[k][j]<)B[k][j]+=mod;
for(int i=k+;i<n;i++)
{
B[i][j]=(B[i][j]-(B[k][j]*B[i][k])%mod)%mod;
if(B[i][j]<)B[i][j]+=mod;
}
}
ans*=B[k][k];
ans%=mod;
if(ans<)ans+=mod;
}
ans*=B[n-][n-];
ans%=mod;
if(flag)ans=-ans;
if(ans<)ans+=mod;
return ans;
} LL china_remain()
{
LL a,b,c,c1,c2,x,y,dd,N;
a=d[],c1=r[];
if(c1==)c1=d[];
for(int i=;i<len;i++)
{
b=d[i],c2=r[i];
ex_gcd(a,b,dd,x,y);
c=c2-c1;
LL b1=b/dd;
x=((c/dd*x)%b1+b1)%b1;
c1=a*x+c1;
a=a*b1;
}
return c1%m;
}
int main()
{
prime();
while(cin>>n>>m)
{
deal(m);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
cin>>A[i][j];
if(m==)
{
cout<<<<endl;
continue;
}
for(int i=;i<len;i++)
{
r[i]=gauss(d[i]);
}
cout<<china_remain()<<endl;
}
return ;
读入挂
inline bool scan(int &num){
bool isN = false;
char in = getchar();
if (in == EOF) return false;
while (in != '-' && ((in < '') || in > '')) in = getchar();
if (in == '-') isN = true, num = ; else num = in - '';
while (in = getchar(), in >= '' && in <= '') num *= , num += in - '';
if (isN) num = -num;
return true;
} inline bool scan_lf(double &num){
double Dec = 0.1;
bool isN = false, isD = false;
char in = getchar();
if (in == EOF) return false;
while (in != '-' && in != '.' && (in < '' || in > '')) in = getchar();
if (in == '-') isN = true, num = ; else
if (in == '.') isD = true, num = ; else num = in - '';
if (!isD) while (in = getchar(), in >= '' && in <= '') num *= , num += in - '';
if (in != '.'){ if (isN) num = -num; return true;}
else{ while (in = getchar(), in >= '' && in <= '') num += Dec * (in - ''), Dec *= 0.1;}
if (isN) num = -num;
return true;
}
ACM常用模板整理的更多相关文章
- ACM算法模板整理
史诗级ACM模板整理 基本语法 字符串函数 istream& getline (char* s, streamsize n ); istream& getline (char* s, ...
- ACM常用模板
数论: 中国剩余定理(互质与非互质通用版) ],r[]; int e_gcd(int a,int b,int &x,int &y) { ) { x=; y=; return a; } ...
- ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)
ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)
- idea教程视频以及常用插件整理
最近在同事的强烈安利下把eclipse换成idea了,本以为需要经历一个艰难的过渡期,谁知道不到3天就深感回不去了. 哎,只能说有时候人的惰性是多么可怕! idea实在是太太太强大了. 不要再问原因. ...
- NiosII常用函数整理
NiosII常用函数整理 IO操作函数函数原型:IORD(BASE, REGNUM) 输入参数:BASE为寄存器的基地址,REGNUM为寄存器的偏移量函数说明:从基地址为BASE的设备中读取寄存器中偏 ...
- ACM常用算法及练习(2)
ACM常用算法及练习 知识类型 重要度 容易度 应掌握度 典型题 其他 数据结构(5) 链表 ★★☆ ★★★ ★★☆ 栈 stack ★★★ ★★★ ★★★ HLoj120 ...
- ACM常用算法及练习(1)
ACM常用算法及练习 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打出来. 1.最短 ...
- NDK(10)Android.mk各属性简介,Android.mk 常用模板
参考 : http://blog.csdn.net/hudashi/article/details/7059006 本文内容: Android.mk简介, 各属性表, 常用Android.mk模板 1 ...
- MAC机常用快捷键整理表格
MAC机常用快捷键整理表格 范围 快捷键 说明 图形 (Command 键)在某些 Apple 键盘上,此键也可能为标志() Control (Control 键) Alt Opt ...
随机推荐
- 从源码中无法看出函数所在的js脚本的解决方法
通过设置断点调试使js脚本自动出现
- 三星系列NXP系列核心板设计研发-迅为嵌入式ARM方案提供商
多种核心板平台,从硬件原型设计.layout.硬件驱动,操作系统移植.中间到上层应用等方面. 三星系列核心板: 1. SCP-4412核心板 三星Exynos4412 四核 Cortex-A9 主频为 ...
- (转)使用JDK中的Proxy技术实现AOP功能
http://blog.csdn.net/yerenyuan_pku/article/details/52863780 AOP技术在企业开发中或多或少都会用到,但用的最多的大概就是做权限系统时,在做权 ...
- win10下安装使用mysql-5.7.23-winx64
下载MySQLhttps://dev.mysql.com/downloads/file/?id=478884 解压到文件,此例为D盘根目录 在mysql-5.7.23-winx64目录下创建[my.i ...
- sysUpload.vue上传组件 的时候 看进度的时候 不要mock 注释掉 // if (process.env.NODE_ENV !== 'production') require('@/mock')
上传组件 的时候 看进度的时候 不要mock 注释掉 // if (process.env.NODE_ENV !== 'production') require('@/mock') <!-- * ...
- 弹跳加载动画特效Bouncing loader
一款非常常用的css 加载动画,这款CSS3 Loading动画主要由几个小球通过规律的上下跳动,渐隐渐显而成,效果十分生动.流畅.兼容IE8以上,尤其适合在移动端中使用,基本代替了图片实现加载的效果 ...
- LayuI固定块关闭
1.近期项目使用了layui的固定块,但是当到某个独立页面时,固定块还在,就显得突兀: 2.通过F12查看,发现代码: <ul class="layui-fixbar" st ...
- ios之coredata
Core Data数据持久化是对SQLite的一个升级,它是ios集成的,在说Core Data之前,我们先说说在CoreData中使用的几个类. (1)NSManagedObjectModel(被管 ...
- Map与对象关系的思考之P1563玩具谜题
P1563 玩具谜题 结论: map在一些情况有种"对象"的意味,在JSON中,对象可以用K-V格式存储:mybatis中参数是map或者对象都可以实现解析...k-v格式的数据存 ...
- 使用Eclipse中的反编译插件jadClipse查看Class源码
功安装完插件jadClipse 之后便可以查看源码class文件了 但是对于自己代码的class文件,直接复制过来却看不到,需要以下操作. 将此文件以及文件夹直接拷贝到Eclipse中发现 右击项目- ...