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实现跨域的方法
由于同源策略的限制,XMLHttpRequest只允许请求当前源(包含域名.协议.端口)的资源. json与jsonp的区别: JSON是一种数据交换格式,而JSONP是一种依靠开发人员创造出的 ...
- Mybatis(一)入门
mybatis使用的三个部分数据查询主体 : SqlSession查询映射层 : Mapper接口数据维护层 : Bean 设计一.添加maven依赖<!-- mybatis依赖 -->& ...
- Java文件编译与反编译:javac命令和javap命令
1.创建一个Test.java文件,并输入内容 public class Test{ private int m; public int inc(){ return m + 1; } } 2.使用ja ...
- TWaver3D直线、曲线、曲面的绘制
插播一则广告(长期有效) TWaver需要在武汉招JavaScript工程师若干 要求:对前端技术(JavasScript.HTML.CSS),对可视化技术(Canvas.WebGL)有浓厚的兴趣 基 ...
- API对接中经常会出现的签名获取,这只是某一种,仅供给有需要的人参考
要求: 1.对所有传入参数(含系统参数和接口参数)按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式.(即 key1=value1&key2=value2…)拼接 ...
- mysql系列安装
Mysql的5种安装方法:1.yum/rpm安装(适合要求不高,并发不大,公司内部,企业内部一些应用场景)2.编译安装(在线高并发业务)3.二进制安装(编译安装后,使用自带工具打包,然后拷贝到相同平台 ...
- 用springmvc的@RequestBody和@ResponseBody 接收和响应json格式数据
1.controller @Controller @RequestMapping("/rest/v1") public class WelcomeController { @Req ...
- 第一讲:vcs simulation basic
要求: 1.complie a verilog/systemverilog design using vcs 2.simulate a verilog/systemverilog design vcs ...
- python_函数递归
函数递归 函数递归:函数的递归调用,即在函数调用的过程中,又直接或间接地调用了函数本身 # import sys # print(sys.getrecursionlimit()) # sys.setr ...
- LeetCode(169)Majority Element
题目 Given an array of size n, find the majority element. The majority element is the element that app ...