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 ...
随机推荐
- 如何实现Windows宿主系统和虚拟机ubuntu系统文件互相访问
我的宿主操作系统是Windows 10,使用Oracle的Virtual Box安装了Ubuntu. 因为工作需要我经常得在两个系统之间互相拷贝一些数据,下面是具体步骤,可以实现Windows 10和 ...
- 程序员面试系列之Java单例模式的攻击与防御
我写的程序员面试系列 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么是Java ...
- HttpClient 接口调用
String url = "http://127.0.0.1:8080/api"; //然后根据表名获取公司信息 HttpPost httppost = new HttpPost( ...
- 使用docker搭建gitlab 服务器
本次使用的docker版本为 1.首先需要安装docker. 2.启动docker后,service docker start 3.拉取镜像 docker pull gitlab/gitlab- ...
- spring使用elasticsearchrepository时间格式的问题Invalid format: "XXXX-XX-XX" is malformed at "-XX-XX"
Invalid format: "XXXX-XX-XX" is malformed at "-XX-XX" 新手,刚接触elasticsearch遇到的问题. ...
- C++函数形参为指针和指针引用的区别
区别: 1.指针传参被调用函数的指针变量在栈内存中重新申请内存. 2.指针引用传参被调用函数的指针变量与调用函数的指针变量共用一块空间. // PointerCite.cpp : 定义控制台应用程序的 ...
- [LUOGU] P3611 [USACO17JAN]Cow Dance Show奶牛舞蹈
https://www.luogu.org/problemnew/show/P3611 二分答案+优先队列 二分O(logn) 判一次正确性O(nlogn) 总体O(nlognlogn) 为了让pri ...
- mysql踩坑
com.mysql.cj.core.exceptions.InvalidConnectionAttributeException: The server time zone value '****** ...
- Week06-继承、多态、抽象类与接口
Week06-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键字:接口,Comparable,interface关键字,Comparator,继承 ...
- Django框架基础知识05-自定义模板标签与过滤器
根据一定规则,自己定义出符合需求功能的.用在任何你有需求的地方,因为内置的满足不了我们的需求,不同的东西有不同的定义规则 目前最最重要的就是HOW 一 文件路径配置: templates 存放自定义 ...