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 ...
随机推荐
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'needDao' defined in URL
这个是我修改过后的mapper,是我的mapper中的空间地址写错了呢
- SEO 第二章
SEO第二章 1. 掌握搜索引擎工作原理(重点) 2. 了解百度算法 3. 关键词的分类 一.什么是搜索引擎? 搜索引擎是用来实现搜索服务的,说白了搜索引擎也属于一种网站. 浏览器是用来加载网站 ...
- 三星系列NXP系列核心板设计研发-迅为嵌入式ARM方案提供商
多种核心板平台,从硬件原型设计.layout.硬件驱动,操作系统移植.中间到上层应用等方面. 三星系列核心板: 1. SCP-4412核心板 三星Exynos4412 四核 Cortex-A9 主频为 ...
- python基础一 day3 列表方法
ls=['a','b','c','d','a','b','c','d']lst=['e','f','g','h']# 增加# ls.append('a') 将元素a添加至列表ls的尾部# ls.ext ...
- 查看本机的ip地址
ifconfig可以查看本机的ip地址:inet addr:10.108.104.185
- linux查看内存和释放内存
linux: 查看内存:free -m 释放内存:echo 1 > /proc/sys/vm/drop_caches
- java session cookie的使用
Cookie; Session; URL重写; cookie在J2EE项目中的使用,Java中把Cookie封装成了java.servlet.http.Cookie类.每个Cookie都是该Cooki ...
- git命令(使用visual studio)
拉取,提取,合并 提交到本地 切换分支 创建分支 推送到远端 删除本地分支 删除远程分支
- 解决sqlplus无法退格问题
# wget http://download.openpkg.org/components/cache/rlwrap/rlwrap-0.42.tar.gz # tar -zxf rlwrap-0. ...
- Jvm:性能调优监控工具
现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 .... ...