zoukankan      html  css  js  c++  java
  • 模板

    线段树 1

    #include<bits/stdc++.h>
    using namespace std;
    using LL=long long;
    const LL N=1e5+2;
    struct tree {
    	LL l,r,sum,tag;
    } tr[N<<2];
    #define l(x) tr[x].l
    #define r(x) tr[x].r
    #define sum(x) tr[x].sum
    #define tag(x) tr[x].tag
    LL a[N];
    void build(LL x,LL l,LL r) {
    	l(x)=l,r(x)=r;
    	if(l==r) {
    		sum(x)=a[l];
    		return;
    	}
    	LL mid=(l+r)>>1;
    	build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    	sum(x)=sum(x<<1)+sum(x<<1|1);
    }
    inline void spread(int x) {
    	if(tag(x)) {
    		sum(x<<1)+=tag(x)*(r(x<<1)-l(x<<1)+1);
    		sum(x<<1|1)+=tag(x)*(r(x<<1|1)-l(x<<1|1)+1);
    		tag(x<<1)+=tag(x),tag(x<<1|1)+=tag(x),tag(x)=0;
    	}
    }
    void add(LL x,LL l,LL r,LL del) {
    	if(l<=l(x)&&r(x)<=r) {
    		sum(x)+=del*(r(x)-l(x)+1);
    		tag(x)+=del;
    		return;
    	}
    	spread(x);
    	LL mid=(l(x)+r(x))>>1;
    	if(l<=mid) {
    		add(x<<1,l,r,del);
    	}
    	if(mid<r) {
    		add(x<<1|1,l,r,del);
    	}
    	sum(x)=sum(x<<1)+sum(x<<1|1);
    }
    LL query(LL x,LL l,LL r) {
    	if(l<=l(x)&&r(x)<=r) {
    		return sum(x);
    	}
    	spread(x);
    	LL mid=(l(x)+r(x))>>1,sum=0;
    	if(l<=mid) {
    		sum=query(x<<1,l,r);
    	}
    	if(mid<r) {
    		sum+=query(x<<1|1,l,r);
    	}
    	return sum;
    }
    int main() {
    	LL n,m;
    	scanf("%lld %lld",&n,&m);
    	for(LL i=1; i<=n; i++) {
    		scanf("%lld",a+i);
    	}
    	build(1,1,n);
    	while(m--) {
    		LL opt,x,y;
    		scanf("%lld %lld %lld",&opt,&x,&y);
    		if(opt^2) {
    			LL k;
    			scanf("%lld",&k);
    			add(1,x,y,k);
    		} else {
    			printf("%lld
    ",query(1,x,y));
    		}
    	}
    	return 0;
    }
    

    树状数组 1

    #include<bits/stdc++.h>
    using namespace std;
    inline int lowbit(int x) {
    	return x&(-x);
    }
    const int N=5e5+5;
    int n,tr[N<<2];
    inline void add(int x,int del) {
    	while(x<=n) {
    		tr[x]+=del,x+=lowbit(x);
    	}
    }
    inline int query(int x) {
    	int sum=0;
    	while(x>0) {
    		sum+=tr[x],x-=lowbit(x);
    	}
    	return sum;
    }
    int main() {
    	int m;
    	scanf("%d %d",&n,&m);
    	for(int i=1,x; i<=n; i++) {
    		scanf("%d",&x),add(i,x);
    	}
    	while(m--) {
    		int x,y,z;
    		scanf("%d %d %d",&x,&y,&z);
    		if(x==1) {
    			add(y,z);
    		} else {
    			printf("%d
    ",query(z)-query(y-1));
    		}
    	}
    	return 0;
    }
    

    最小费用最大流

    #include<bits/stdc++.h>
    using namespace std;
    const int N=100010;
    bool vis[N];
    int n,m,s,t,x,y,z,f,dis[N],pre[N],last[N],flow[N],maxflow,mincost;
    //dis最小花费;pre每个点的前驱;last每个点的所连的前一条边;flow源点到此处的流量
    struct Edge {
        int v,nxt,flow,dis;//flow流量 dis花费
    } e[N];
    int head[N],cnt;
    queue<int> q;
    void add_edge(int from,int v,int flow,int dis) {
        e[++cnt].nxt=head[from],e[cnt].v=v,e[cnt].flow=flow,e[cnt].dis=dis,head[from]=cnt;
    }
    bool spfa(int s,int t) {
        memset(dis,0x7f,sizeof(dis)),memset(flow,0x7f,sizeof(flow));
        memset(vis,0,sizeof(vis));
        q.push(s),vis[s]=1,dis[s]=0,pre[t]=-1;
        while(q.size()) {
            int now=q.front();
            q.pop(),vis[now]=0;
            for(int i=head[now]; i!=-1; i=e[i].nxt) {
                if(e[i].flow>0 && dis[e[i].v]>dis[now]+e[i].dis) {//正边
                    dis[e[i].v]=dis[now]+e[i].dis,pre[e[i].v]=now;
    				last[e[i].v]=i,flow[e[i].v]=min(flow[now],e[i].flow);
                    if(!vis[e[i].v]) {
                        vis[e[i].v]=1,q.push(e[i].v);
                    }
                }
            }
        }
        return pre[t]^-1;
    }
    int main() {
        memset(head,-1,sizeof(head)),cnt=-1;//初始化
        scanf("%d%d%d%d",&n,&m,&s,&t);
        for(int i=1; i<=m; i++) {
            scanf("%d%d%d%d",&x,&y,&z,&f);
            add_edge(x,y,z,f); add_edge(y,x,0,-f);
            //反边的流量为0,花费是相反数
        }
        while(spfa(s,t)) {
            int now=t;
            maxflow+=flow[t],mincost+=flow[t]*dis[t];
            while(now^s) {//从源点一直回溯到汇点
                e[last[now]].flow-=flow[t],e[last[now]^1].flow+=flow[t],now=pre[now];
            }
        }
        printf("%d %d",maxflow,mincost);
        return 0;
    }
    

    快速幂||取余运算

    #include<bits/stdc++.h>
    using namespace std;
    using LL=long long;
    LL pow(LL x,LL y,LL p) {
    	LL ans=1;
    	while(y) {
    		if(y&1) {
    			ans=ans*x%p;
    		}
    		x=x*x%p,y>>=1;
    	}
    	return ans;
    }
    int main() {
    	LL b,p,k;
    	scanf("%lld %lld %lld",&b,&p,&k);
    	printf("%lld^%lld mod %lld=%lld",b,p,k,pow(b,p,k)%k);
    	return 0;
    }
    

    多项式乘法(FFT)

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const LL mod=998244353,G=3,N=2200000;
    LL n,m,iN,a[N],b[N],tr[N];
    void inc(LL &a,LL b) {
    	a+=b;
    	if(a>=mod) {
    		a-=mod;
    	}
    }
    void dec(LL &a,LL b) {
    	a-=b;
    	if(a<0) {
    		a+=mod;
    	}
    }
    LL _inc(LL a,LL b) {
    	a+=b;
    	if(a>=mod) {
    		a-=mod;
    	}
    	return a;
    }
    LL _dec(LL a,LL b) {
    	a-=b;
    	if(a<0) {
    		a+=mod;
    	}
    	return a;
    }
    LL mi(LL a,LL k=mod-2) {
    	LL sum=1;
    	while(k) {
    		if(k&1) {
    			sum=sum*a%mod;
    		}
    		a=a*a%mod,k>>=1;
    	}
    	return sum;
    }
    const LL iG=mi(G);
    void NTT(LL *f,bool flag) {
    	for(LL i=0; i<n; i++) {if(i<tr[i]){swap(f[i],f[tr[i]]);
    	}
    	}
    	for(LL p=2; p<=n; p<<=1) {
    		LL angle=mi(flag?G:iG,(mod-1)/p);
    		for(LL k=0; k<n; k+=p) {
    			LL buf=1;
    			for(LL i=k; i<k+p/2; i++) {
    				LL tt=f[i+p/2]*buf%mod;
    				f[i+p/2]=_dec(f[i],tt),inc(f[i],tt);
    				buf=buf*angle%mod;
    			}
    		}
    	}
    }
    int main() {
    	scanf("%lld%lld",&n,&m);
    	for(LL i=0; i<=n; i++) {
    		scanf("%lld",a+i);
    	}
    	for(LL i=0; i<=m; i++) {
    		scanf("%lld",b+i);
    	}
    	for(m+=n,n=1; n<=m; n<<=1);
    	for(LL i=0; i<n; i++) {
    		tr[i]=(tr[i>>1]>>1)|((i&1)?n>>1:0);
    	}
    	NTT(a,1),NTT(b,1);
    	for(LL i=0; i<n; i++) {
    		a[i]=a[i]*b[i]%mod;
    	}
    	NTT(a,0),iN=mi(n);
    	for(LL i=0; i<=m; i++) {
    		printf("%lld ",a[i]*iN%mod);
    	}
    }
    

    KMP 字符串匹配

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+2;
    int kmp[N]= {0};
    char a[N],b[N];
    int main() {
    	scanf("%s%s",a+1,b+1);
    	int la=strlen(a+1),lb=strlen(b+1),j=0;
    	for(int i=2; i<=lb; i++) {
    		while(j>0&&(b[i]^b[j+1])) {
    			j=kmp[j];
    		}
    		if(b[i]==b[j+1]) {
    			j++;
    		}
    		kmp[i]=j;
    	}
    	j=0;
    	for(int i=1; i<=la; i++) {
    		while(j>0&&(a[i]^b[j+1])) {
    			j=kmp[j];
    		}
    		if(a[i]==b[j+1]) {
    			j++;
    		}
    		if(j==lb) {
    			printf("%d
    ",i-lb+1);
    			j=kmp[j];
    		}
    	}
    	for(int i=1; i<=lb; i++) {
    		printf("%d ",kmp[i]);
    	}
    	return 0;
    }
    

    差分约束算法

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e4+5;
    struct edge {
    	int v,w,nxt;
    } e[N];
    int n,m,head[N],cnt,dis[N],tot[N];
    bitset<N> vis;
    void add(int u,int v,int w) {
    	e[++cnt].v=v,e[cnt].w=w,e[cnt].nxt=head[u],head[u]=cnt;
    }
    bool spfa(int s) {
    	queue<int> q;
    	memset(dis,63,sizeof(dis));
    	dis[s]=0,vis[s]=1;
    	q.push(s);
    	while(q.size()) {
    		int u=q.front();
    		q.pop();
    		vis[u]=0;
    		for(int i=head[u]; i; i=e[i].nxt) {
    			int v=e[i].v;
    			if(dis[v]>dis[u]+e[i].w) {
    				dis[v]=dis[u]+e[i].w;
    				if(!vis[v]) {
    					vis[v]=1,tot[v]++;
    					if(tot[v]==n+1) {
    						return 0;
    					}
    					q.push(v);
    				}
    			}
    		}
    	}
    	return 1;
    }
    int main() {
    	scanf("%d %d",&n,&m);
    	for(int i=1; i<=n; i++) {
    		add(0,i,0);
    	}
    	for(int i=1,v,u,w; i<=m; i++) {
    		scanf("%d %d %d",&v,&u,&w),add(u,v,w);
    	}
    	if(!spfa(0)) {
    		puts("NO");
    		return 0;
    	}
    	for(int i=1; i<=n; i++) {
    		printf("%d ",dis[i]);
    	}
    	return 0;
    }
    

    网络最大流

    #include<bits/stdc++.h>
    using namespace std;
    using LL=long long;
    const LL N=1002,M=5002,inf=1e9;
    struct edge {
    	LL to,nxt,w;
    } e[M<<1];
    LL n,m,s,t,cnt=1,head[N],d[N];
    void add(int u,int v,int w) {
    	e[++cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt,e[cnt].w=w;
    }
    bool bfs() {
    	queue<LL> q;
    	q.push(s);
    	for(int i=1; i<=n; i++) {
    		d[i]=inf;
    	}
    	d[s]=0;
    	while(q.size()) {
    		LL x=q.front();
    		q.pop();
    		for(LL i=head[x]; i; i=e[i].nxt) {
    			LL v=e[i].to;
    			if(e[i].w&&d[v]==inf) {
    				q.push(v),d[v]=d[x]+1;
    				if(v==t) {
    					return 1;
    				}
    			}
    		}
    	}
    	return 0;
    }
    LL dfs(LL x,LL sum) {
    	if(x==t) {
    		return sum;
    	}
    	LL res=0;
    	for(int i=head[x]; i&&sum; i=e[i].nxt) {
    		int v=e[i].to;
    		if(e[i].w>0&&d[v]==d[x]+1) {
    			int k=dfs(v,min(sum,e[i].w));
    			if(!k) {
    				d[v]=inf;
    			}
    			e[i].w-=k,e[i^1].w+=k,res+=k,sum-=k;
    		}
    	}
    	return res;
    }
    int main() {
    	scanf("%lld %lld %lld %lld",&n,&m,&s,&t);
    	for(LL i=1,u,v,w; i<=m; i++) {
    		scanf("%lld %lld %lld",&u,&v,&w),add(u,v,w),add(v,u,0);
    	}
    	LL ans=0;
    	while(bfs()) {
    		ans+=dfs(s,inf);
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

    卢卡斯定理

    #include<bits/stdc++.h>
    #define N 100010
    using namespace std;
    using LL=long long;
    LL p,a[N];
    LL pow(LL x,LL y) {
    	x%=p;
    	LL ans=1;
    	while(y) {
    		if(y&1) {
    			ans=ans*x%p;
    		}
    		x=x*x%p,y>>=1;
    	}
    	return ans;
    }
    LL C(LL n,LL m) {
    	if(m>n) {
    		return 0;
    	}
    	return (a[n]*pow(a[m],p-2))%p*pow(a[n-m],p-2)%p;
    }
    LL Lucas(LL n,LL m) {
    	if(!m) {
    		return 1;
    	}
    	return C(n%p,m%p)*Lucas(n/p,m/p)%p;
    }
    int main() {
    	LL T;
    	scanf("%lld",&T);
    	while(T--) {
    		LL n,m;
    		scanf("%lld %lld %lld",&n,&m,&p);
    		a[0]=1;
    		for(LL i=1; i<=p; i++) {
    			a[i]=(a[i-1]*i)%p;
    		}
    		printf("%lld
    ",Lucas(n+m,n));
    	}
    }
    

    树状数组 2

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e5+2;
    int n,tr[N<<2];
    inline int lowbit(int x) {
    	return x&(-x);
    }
    void add(int p,int del) {
    	while(p<=n) {
    		tr[p]+=del;
    		p+=lowbit(p);
    	}
    }
    int query(int p) {
    	int sum=0;
    	while(p>0) {
    		sum+=tr[p];
    		p-=lowbit(p);
    	}
    	return sum;
    }
    int main() {
    	int m;
    	scanf("%d %d",&n,&m);
    	int lst=0;
    	for(int i=1,x; i<=n; i++) {
    		scanf("%d",&x);
    		add(i,x-lst);
    		lst=x;
    	}
    	while(m--) {
    		int op,x,y,k;
    		scanf("%d %d",&op,&x);
    		if(op^2) {
    			scanf("%d %d",&y,&k);
    			add(x,k),add(y+1,-k);
    		} else {
    			printf("%d
    ",query(x));
    		}
    	}
    	return 0;
    }
    

    线性筛素数

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e8+5;
    int cnt,p[N];
    bitset<N> is;
    int main() {
    	int n,q;
    	scanf("%d %d",&n,&q);
    	for(int i=2; i<=n; i++) {
    		if(!is[i]) {
    			p[++cnt]=i;
    		}
    		for(int j=1; j<=cnt; j++) {
    			if(1LL*i*p[j]>=N) {
    				break;
    			}
    			is[i*p[j]]=1;
    			if(i*p[j]==0) {
    				break;
    			}
    		}
    	}
    	while(q--) {
    		int k;
    		scanf("%d",&k),printf("%d
    ",p[k]);
    	}
    	return 0;
    }
    

    AC 自动机

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+6;
    int n;
    int tr[N][26],tot,e[N],fail[N];
    void insert(char *s) {
    	int u=0;
    	for(int i=1; s[i]; i++) {
    		if(!tr[u][s[i]-'a']) {
    			tr[u][s[i]-'a']=++tot;
    		}
    		u=tr[u][s[i]-'a'];
    	}
    	e[u]++;
    }
    void build() {
    	queue<int> q;
    	for(int i=0; i<26; i++) {
    		if(tr[0][i]) {
    			q.push(tr[0][i]);
    		}
    	}
    	while(q.size()) {
    		int u=q.front();
    		q.pop();
    		for(int i=0; i<26; i++) {
    			if(tr[u][i]) {
    				fail[tr[u][i]]=tr[fail[u]][i],q.push(tr[u][i]);
    			} else {
    				tr[u][i]=tr[fail[u]][i];
    			}
    		}
    	}
    }
    int query(char *s) {
    	int u=0,res=0;
    	for(int i=1; s[i]; i++) {
    		u=tr[u][s[i]-'a'];
    		for(int j=u; j&&e[j]^-1; j=fail[j]) {
    			res+=e[j],e[j]=-1;
    		}
    	}
    	return res;
    }
    char s[N];
    int main() {
    	scanf("%d",&n);
    	for(int i=1; i<=n; i++) {
    		scanf("%s",s+1),insert(s);
    	}
    	build(),scanf("%s",s+1),printf("%d",query(s));
    	return 0;
    }
    

    二分图最大匹配

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1005;
    int n,m,e,ans,match[N];
    bool a[N][N],vis[N];
    bool dfs(int x) {
    	for(int i=1; i<=m; i++) {
    		if(!vis[i]&&a[x][i]) {
    			vis[i]=1;
    			if(!match[i]||dfs(match[i])) {
    				match[i]=x;
    				return 1;
    			}
    		}
    	}
    	return 0;
    }
    int main() {
    	scanf("%d %d %d",&n,&m,&e);
    	for(int i=1,u,v; i<=e; i++) {
    		scanf("%d %d",&u,&v),a[u][v]=1;
    	}
    	for (int i=1; i<=n; i++){
            ans+=dfs(i);
            memset(vis,0,sizeof(vis));
        }
        printf("%d",ans);
    	return 0;
    }
    

    可持久化线段树 1

    #include<bits/stdc++.h>
    using namespace std;
    struct abc {
    	int l,r,val;
    } tree[1000001<<5];
    int top,a[1000005],root[1000005];
    int New(int node) {
    	tree[++top]=tree[node];
    	return top;
    }
    int build(int node,int begin,int end) {
        node=++top;
        if(begin==end) {
            tree[node].val=a[begin];
            return top;
        }
        int mid=(begin+end)>>1;
        tree[node].l=build(tree[node].l,begin,mid);
        tree[node].r=build(tree[node].r,mid+1,end);
        return node;
    }
    int update(int node,int begin,int end,int x,int val) {
        node=New(node);
        if(begin==end) {
            tree[node].val=val;
        } else {
            int mid=(begin+end)>>1;
            if(x<=mid) {
                tree[node].l=update(tree[node].l,begin,mid,x,val);
            } else {
                tree[node].r=update(tree[node].r,mid+1,end,x,val);
            }
        }
        return node;
    }
    int query(int node,int begin,int end,int x) {
        if(begin==end) {
            return tree[node].val;
        } else {
            int mid=(begin+end)>>1;
            if(x<=mid) {
                return query(tree[node].l,begin,mid,x);
            } else {
                return query(tree[node].r,mid+1,end,x);
            }
        }
    }
    int main(){
    	int n,m;
        scanf("%d %d",&n,&m);
        for(int i=1; i<=n; i++) {
        	scanf("%d",a+i);
        }
        root[0]=build(0,1,n);
        for(int i=1,rt,mode,x; i<=m; i++){
            scanf("%d %d %d",&rt,&mode,&x);
            if(mode==1) {
            	int y;
                scanf("%d",&y);
                root[i]=update(root[rt],1,n,x,y);
            } else {
                printf("%d
    ",query(root[rt],1,n,x));
                root[i]=root[rt];
            }
        }
    }
    

    ST表

    #include<bits/stdc++.h>
    using namespace std;
    int f[100005][40];
    inline int ask(int l,int r) {
    	int k=(int)(log(r-l+1)/log(2));
    	return max(f[l][k],f[r-(1<<k)+1][k]);
    }
    int main() {
    	int n,m;
    	scanf("%d %d",&n,&m);
    	for(int i=1; i<=n; i++) {
    		scanf("%d",f[i]);
    	}
    	int t=log2(n);
    	for(int j=1; j<=t; j++) {
    		for (int i=1; i<=n-(1<<j)+1; i++) {
    			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    		}
    	}
    	for(int i=1,l,r; i<=m; i++) {
    		scanf("%d %d",&l,&r);
    		printf("%d
    ",ask(l,r));
    	}
    	return 0;
    }
    

    nim 游戏

    #include<bits/stdc++.h>
    using namespace std;
    int main() {
    	int T;
    	scanf("%d",&T);
    	while(T--) {
    		int n;
    		scanf("%d",&n);
    		int tmp;
    		scanf("%d",&tmp);
    		for(int i=1; i<n; i++) {
    			int x;
    			scanf("%d",&x),tmp^=x;
    		}
    		if(tmp) {
    			puts("Yes");
    		} else {
    			puts("No");
    		}
    	}
    	return 0;
    }
    

    乘法逆元

    #include<bits/stdc++.h>
    using namespace std;
    inline int read() {
    	int ans=0,f=1;
    	char c=getchar();
    	while(c<'0'||c>'9') {
    		if(c=='-') {
    			f=-1;
    		}
    		c=getchar();
    	}
    	while(c>='0'&&c<='9') {
    		ans=(ans<<3)+(ans<<1)+(c-'0');
    		c=getchar();
    	}
    	return ans*f;
    }
    inline void print(int x) {
    	if(x<0) {
    		x*=-1,putchar('-');
    	}
    	if(x>9) {
    		print(x/10);
    	}
    	putchar(x%10+'0');
    }
    int ans[3000005]= {0,1};
    int main() {
    	int n=read(),p=read();
    	putchar('1'),putchar('
    ');
    	for(int i=2; i<=n; i++) {
    		ans[i]=1LL*(p-p/i)*ans[p%i]%p;
    		print(ans[i]),putchar('
    ');
    	}
    }
    

    知识共享许可协议

    本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。

    限于本人水平,如果文章有表述不当之处,还请不吝赐教。

  • 相关阅读:
    钱多多软件制作04
    团队项目01应用场景
    HDU 4411 arrest
    HDU 4406 GPA
    HDU 3315 My Brute
    HDU 3667 Transportation
    HDU 2676 Matrix
    欧拉回路三水题 POJ 1041 POJ 2230 POJ 1386
    SPOJ 371 BOXES
    POJ 3422 Kaka's Matrix Travels
  • 原文地址:https://www.cnblogs.com/Sam2007/p/14583646.html
Copyright © 2011-2022 走看看