NOIP2017 Day-1 模板荟萃

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int N,Q;
struct Node{
    int l,r;
    long long sum;
}tree[MAXN*4];
long long lazy[MAXN*4];
void pushdown(int k){
    int mid=tree[k].l+tree[k].r>>1;
    tree[k<<1].sum+=lazy[k]*(mid-tree[k].l+1);
    tree[k<<1|1].sum+=lazy[k]*(tree[k].r-mid);
    lazy[k<<1]+=lazy[k],lazy[k<<1|1]+=lazy[k],lazy[k]=0; 
}
void build_tree(int k,int l,int r){
    tree[k].l=l,tree[k].r=r;
    if(l==r){tree[k].sum=read();return ;}
    int mid=l+r>>1;
    build_tree(k<<1,l,mid);build_tree(k<<1|1,mid+1,r);
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}
void addall(int k,int l,int r,long long x){
    if(tree[k].l>=l&&tree[k].r<=r){
        tree[k].sum+=x*(tree[k].r-tree[k].l+1);lazy[k]+=x;return ;}
    if(tree[k].r<l||tree[k].l>r)return ;
    pushdown(k);
    addall(k<<1,l,r,x);addall(k<<1|1,l,r,x);
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}
long long query(int k,int l,int r){
    if(tree[k].l>=l&&tree[k].r<=r)return tree[k].sum;
    if(tree[k].r<l||tree[k].l>r)return 0;
    pushdown(k);
    return query(k<<1,l,r)+query(k<<1|1,l,r);
}
int main()
{
    N=read(),Q=read();
    build_tree(1,1,N);
    while(Q--){
        int opt=read(),L=read(),R=read();
        if(opt==1)addall(1,L,R,read());
        if(opt==2)printf("%lld
",query(1,L,R));
    }
    return 0;
} 
线段树
#include<bits/stdc++.h>
#define MAXN 100005
#define INF 0x7f7f7f7f
using namespace std;
int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int N,M,S,T,last[MAXN],cnt=1,ans,depth[MAXN];
struct Edge{
    int other,pre,val;
}e[MAXN*2];
void connect(int x,int y,int z){
    e[++cnt]=(Edge){y,last[x],z};
    last[x]=cnt;
}
bool BFS(){
    memset(depth,0,sizeof depth);
    queue <int> q;
    depth[S]=1;q.push(S);
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=last[x];i;i=e[i].pre){
            int to=e[i].other;
            if(e[i].val&&!depth[to]){
                depth[to]=depth[x]+1;
                if(to==T)return 1;
                q.push(to);
            }
        }
    }
    return 0;
}
int dinic(int u,int flow){
    if(u==T)return flow;
    int rest=flow;
    for(int i=last[u];i;i=e[i].pre){
        int to=e[i].other;
        if(depth[u]+1==depth[to]&&e[i].val&&rest){
            int tmp=dinic(to,min(rest,e[i].val));
            e[i].val-=tmp;
            e[i^1].val+=tmp;
            rest-=tmp;
            if(tmp==0)depth[to]=0;
        }
    }
    return flow-rest;
}
int main()
{
    N=read(),M=read(),S=read(),T=read();
    for(int i=1;i<=M;i++){
        int x=read(),y=read(),z=read();
        connect(x,y,z);connect(y,x,0);
    }
    while(BFS())ans+=dinic(S,INF);
    cout<<ans<<endl;
    return 0;
}
网络流(dinic)
#include<bits/stdc++.h>
#define MAXN 1005
#define INF 0x7f7f7f7f
using namespace std;
int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int N,M,C,cnt,last[MAXN*2],ans,vis[MAXN],link[MAXN];
struct Edge{
    int other,pre;
}e[MAXN*MAXN];
void connect(int x,int y){
    e[++cnt]=(Edge){y,last[x]};
    last[x]=cnt;
}
bool DFS(int x){
    for(int i=last[x];i;i=e[i].pre){
        int to=e[i].other;
        if(!vis[to]){
            vis[to]=1;
            if(!link[to]||DFS(link[to])){
                link[to]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    N=read(),M=read(),C=read();
    for(int i=1;i<=M;i++){
        int x=read(),y=read();
        if(x>N||y>M)continue;         //sb->
        connect(x,y);
    }
    for(int i=1;i<=N;i++){
        memset(vis,0,sizeof vis);
        if(DFS(i))ans++;
    }
    cout<<ans<<endl;
    return 0;
}
二分图匹配(匈牙利)
#include<bits/stdc++.h>
#define MAXN 10005
#define MAXM 500005
using namespace std;
int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int N,M,S,cnt,last[MAXN],dis[MAXN];
struct Edge{
    int other,pre,val;
}e[MAXM*2];
void connect(int x,int y,int z){
    e[++cnt]=(Edge){y,last[x],z};
    last[x]=cnt;
}
struct Node{
    int f,id;
    bool operator <(const Node x)const{
        return f>x.f;
    }
};
void Dijkstra(){
    priority_queue <Node> q; 
    memset(dis,0x3f,sizeof dis);
    dis[S]=0;
    q.push((Node){0,S});
    while(!q.empty()){
        Node x=q.top();
        q.pop();
        for(int i=last[x.id];i;i=e[i].pre){
            int to=e[i].other;
            if(dis[to]>dis[x.id]+e[i].val){
                dis[to]=dis[x.id]+e[i].val;
                q.push((Node){dis[to],to});
            }
        }
    }
    
}
int main(){
    N=read(),M=read(),S=read();
    for(int i=1;i<=M;i++){
        int x=read(),y=read(),z=read();
        connect(x,y,z);
        //connect(y,x,z);
    }
    Dijkstra();
    for(int i=1;i<=N;i++)printf("%d ",dis[i]);
    return 0;
}
最短路(dijkstra)
#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int N,Q,st[MAXN][20],Log[MAXN];
int main()
{
    N=read(),Q=read();
    Log[0]=-1;
    for(int i=1;i<=N;i++)st[i][0]=read(),Log[i]=Log[i>>1]+1;
    for(int j=1;j<=16;j++)
        for(int i=1;i+(1<<j)-1<=N;i++)
            st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
    while(Q--){
        int l=read(),r=read(),k=Log[r-l+1];
        printf("%d
",max(st[l][k],st[r-(1<<k)+1][k]));
    }    
    return 0;
} 
ST表
#include<bits/stdc++.h>
#define MAXN 5005
#define MAXM 200005
using namespace std;
int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int N,M,last[MAXN],cnt,tmp,ans;
bool vis[MAXN];
priority_queue <pair<int,int> > q;
struct Edge{
    int other,pre,val;
}e[MAXM*2];
void connect(int x,int y,int z){
    e[++cnt]=(Edge){y,last[x],z};
    last[x]=cnt;
}
int main()
{
    N=read(),M=read();
    for(int i=1;i<=M;i++){
        int x=read(),y=read(),z=read();
        connect(x,y,z);
        connect(y,x,z);
    }
    q.push(make_pair(0,1));
    while(tmp<N&&!q.empty()){
        while(vis[q.top().second])q.pop();
        int x=q.top().first,y=q.top().second;
        q.pop();
        vis[y]=1,tmp++,ans-=x;
        for(int i=last[y];i;i=e[i].pre)
            if(!vis[e[i].other])q.push(make_pair(-e[i].val,e[i].other));
    }
    if(tmp<N)printf("orz
");
    else printf("%d
",ans);
    return 0;
}
生成树(Prim)
#include<bits/stdc++.h>
#define MAXN 5005
#define MAXM 200005
using namespace std;
int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int N,M,cnt,ans,father[MAXN],tmp;
struct Edge{
    int from,to,val;
    bool operator <(const Edge x)const{
        return val<x.val;
    } 
}e[MAXM];
int find(int x){return father[x]==x?x:father[x]=find(father[x]);}
int main(){
    N=read(),M=read();
    for(int i=1;i<=M;i++)e[i]=(Edge){read(),read(),read()};
    for(int i=1;i<=N;i++)father[i]=i;
    sort(e+1,e+M+1);
    for(int i=1;i<=M;i++){
        int fx=find(e[i].from),fy=find(e[i].to);
        if(fx!=fy){
            father[fx]=fy;
            ans+=e[i].val;
            tmp++;
        }
        if(tmp==N-1){
            printf("%d
",ans);
            return 0;
        }
    }
    printf("orz
");
    return 0;
}
生成树(Kruscal)
#include<bits/stdc++.h>
#define MAXN 500005
using namespace std;
int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int N,Q,root,last[MAXN],cnt,f[MAXN][22],depth[MAXN];
struct Edge{
    int other,pre;
}e[MAXN*2];
void connect(int x,int y){
    e[++cnt]=(Edge){y,last[x]};
    last[x]=cnt;
}
void DFS(int x){
    for(int i=last[x];i;i=e[i].pre){
        int to=e[i].other;
        if(f[x][0]==to)continue;
        depth[to]=depth[x]+1;
        f[to][0]=x;
        DFS(to);
    }
}
int LCA(int x,int y){
    if(depth[x]<depth[y])swap(x,y);
    int d=depth[x]-depth[y];
    for(int i=21;i>=0;i--)
        if(d&(1<<i))x=f[x][i];
    if(x==y)return x;
    for(int i=21;i>=0;i--)
        if(f[x][i]!=f[y][i]){
            x=f[x][i];
            y=f[y][i];
        }
    return f[x][0];
}
int main()
{
    N=read(),Q=read(),root=read();
    for(int i=1;i<=N-1;i++){
        int x=read(),y=read();
        connect(x,y);
        connect(y,x);
    }
    DFS(root);
    for(int j=1;j<=21;j++)
        for(int i=1;i<=N;i++)    
            f[i][j]=f[f[i][j-1]][j-1];
    for(int i=1;i<=Q;i++)
        printf("%d
",LCA(read(),read()));
    return 0;
}
LCA(倍增)
#include<cstdio>
#include<iostream>
#define MAXN 500001
using namespace std;
struct edge{int pre,other;}b[MAXN*2];
struct node{int last,p,depth,h,child,top;}a[MAXN];
int cnt,N,M,x,y,l,root;
void connect(int x1,int x2)
{
    b[++cnt]=(edge){a[x1].last,x2};
    a[x1].last=cnt;
}
void dfs1(int x1)
{
    a[x1].depth=a[a[x1].p].depth+1;
    a[x1].h=1;
    for(int i=a[x1].last;i;i=b[i].pre)
    {
        int x2=b[i].other;
        if(!a[x2].p&&a[x1].p!=x2)
        {
            a[x2].p=x1;
            dfs1(x2);
            a[x1].h+=a[x2].h;
            if(a[a[x1].child].h<a[x2].h)a[x1].child=x2;
        }
    }
}
void dfs2(int x1)
{
    if(x1==a[a[x1].p].child)a[x1].top=a[a[x1].p].top;
    else a[x1].top=x1;
    for(int i=a[x1].last;i;i=b[i].pre)if(a[b[i].other].p==x1)dfs2(b[i].other);
}
int LCA(int x1,int x2)
{
    while(a[x1].top!=a[x2].top)
    {
        if(a[a[x1].top].depth>a[a[x2].top].depth)x1=a[a[x1].top].p;
        else x2=a[a[x2].top].p;
    }
    return a[x1].depth<a[x2].depth?x1:x2;
}
int main()
{
    scanf("%d%d%d",&N,&M,&root);
    for(int i=1;i<=N-1;i++)
    {
        scanf("%d%d",&x,&y);
        connect(x,y);
        connect(y,x);
    }
    dfs1(root);
    dfs2(root);
//  for(int i=1;i<=N;i++)printf("%d ",a[i].top);
    while(M--)
    {
        scanf("%d%d",&x,&y);
        printf("%d
",LCA(x,y));    
    }
    return 0;
}
LCA(树剖)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define MAXN 1000007
using namespace std;
int N,root,tree_size,v;
struct Node{
    int key,l,r,p;    
}a[MAXN];
void print();
int Search(int,int);            //查找值 
void InsertNode(int,int);        //插入结点 
void Treeplant(int,int,int);    //树替代 
void DeleteNode(int,int);        //删除节点 
void Inorder(int);                //中序遍历 
void Leftorder(int);            //左序遍历 
int getmin(int);                //查找最小值 
int getmax(int);                //查找最大值 
int main()
{
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
    {
        scanf("%d",&v);
        InsertNode(1,v);    
    }
    Leftorder(root); 
    system("pause");
    return 0;
}
int Search(int k,int x)
{
    if(x<a[k].key && a[k].l) Search(a[k].l,x);
    else if(x>a[k].key && a[k].r) Search(a[k].r,x);
    else return k;    
}
void InsertNode(int k,int x)
{
    if(tree_size==0)root=++tree_size,a[root].key=x;
    else if(x<=a[k].key){
        if(a[k].l)InsertNode(a[k].l,x);    
        else{
            tree_size++;
            a[tree_size].key=x;
            a[tree_size].p=k;
            a[k].l=tree_size;    
        }    
    }
    else if(x>a[k].key){
        if(a[k].r)InsertNode(a[k].r,x);    
        else{
            tree_size++;
            a[tree_size].key=x;
            a[tree_size].p=k;
            a[k].r=tree_size;    
        }    
    }
}
void Inorder(int k)
{
    printf("%d ",a[k].key);
    if(a[k].l)Inorder(a[k].l);
    if(a[k].r)Inorder(a[k].r);
}
void Leftorder(int k)
{
    if(a[k].l)Leftorder(a[k].l);
    printf("%d ",a[k].key);
    if(a[k].r)Leftorder(a[k].r); 
}
int getmin(int k)
{
    if(!a[k].l)return k;
    return getmin(a[k].l);
}
int getmax(int k)
{
    if(!a[k].r)return k;
    return getmax(a[k].r);
}
void Treeplant(int k,int x,int y)
{
    if(x==root)root=y;
    else if(x==a[a[x].p].l)a[a[x].p].l=y;
    else a[a[x].p].r=y;
    if(a[y].key)a[y].p=a[x].p;
}
void DeleteNode(int k,int x)
{
    if(!a[x].l)Treeplant(k,x,a[x].r);
    else if(!a[x].r)Treeplant(k,x,a[x].l);
    else{
        int y=getmin(a[x].r);
        if(a[y].p!=x)
        {
            Treeplant(1,y,a[y].r);
            a[y].r=a[x].r,a[a[y].r].p=y;    
        }
        Treeplant(1,x,y);
        a[y].l=a[x].l,a[a[y].l].p=y;
    }
}
void print()
{
    printf("这棵树她长这样↓↓
");
    printf("KEY:");for(int i=1;i<=N;i++)printf("%d ",a[i].key);printf("
");
    printf(" P :");for(int i=1;i<=N;i++)printf("%d ",a[i].p);printf("
");
    printf(" L :");for(int i=1;i<=N;i++)printf("%d ",a[i].l);printf("
");
    printf(" R :");for(int i=1;i<=N;i++)printf("%d ",a[i].r);printf("
");    
}
// 8 4 2 6 1 8 4 7 3
二叉查找树BST
#include<bits/stdc++.h>
using namespace std;
int a[100010],N,b[100010],ans; //ans是逆序对个数 
void merge(int,int);
void msort(int,int);
void msort(int l,int r)
{
    if(l==r)return;
    int mid=l+r>>1;
    msort(l,mid);msort(mid+1,r);
    merge(l,r);
}
void merge(int l,int r)
{
    if(l==r)return;
    int mid=l+r>>1;
    int i=l,j=mid+1,t=0;
    while(t<r-l+1){
        if((i<=mid&&a[i]<=a[j])||j>r)b[++t]=a[i++];
        else if(a[i]>a[j]||i>mid){b[++t]=a[j++];if(i<=mid)ans+=(mid-i+1);}
    }
    for(int i=1;i<=t;i++)a[l+i-1]=b[i];
}
归并排序
#include<bits/stdc++.h>
using namespace std;
char s1[1000005],s2[1000005];
int len1,len2,next[1000005];
int main(){
    scanf("%s%s",s1+1,s2+1);
    int len1=strlen(s1+1),len2=strlen(s2+1);
    for(int i=2,j=0;i<=len2;i++){
        while(s2[i]!=s2[j+1]&&j>0)j=next[j];
        if(s2[i]==s2[j+1])next[i]=++j;
    }
    for(int i=1,j=0;i<=len1;i++){
        while(s1[i]!=s2[j+1]&&j>0)j=next[j];
        if(s1[i]==s2[j+1])j++;
        if(j==len2){
            printf("%d
",i-len2+1);
            j=next[j];
        }
    }
    for(int i=1;i<=len2;i++)printf("%d ",next[i]);
    return 0;
}
字符串匹配KMP
#include<bits/stdc++.h>
#define MAXN 10000005
int prime[MAXN],mark[MAXN],cnt,N,M;
int main()
{
    scanf("%d%d",&N,&M);
    for(int i=2;i<=N;i++){
        if(!mark[i])prime[++cnt]=i;
        for(int j=1;prime[j]*i<=N&&j<=cnt;j++){
            mark[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }mark[1]=1; 
    for(int i=1;i<=M;i++){
        int x;scanf("%d",&x);
        mark[x]?puts("No"):puts("Yes");
    }
    return 0;
} 
线性筛素数
#include<bits/stdc++.h>
#define ull unsigned long long 
#define lowbit(a) (a&-a)
#define MAXN 200005 
using namespace std;
int N,M,a[MAXN];
ull c1[MAXN],c2[MAXN];
void add(int pos,ull x)
{
    for(int i=pos;i<=N;i+=lowbit(i))
        c1[i]+=x,c2[i]+=x*pos;
} 
ull sum(int pos)                    //[1,pos]区间和 
{
    ull s=0;
    for(int i=pos;i;i-=lowbit(i))        
        s+=c1[i]*(pos+1)-c2[i];
    return s;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>N;cin>>M;
    for(int i=1;i<=N;i++)
    {
        cin>>a[i];
        add(i,a[i]-a[i-1]);
    }
//    cin>>M;
    while(M--)
    {
        int P,X,Y;
        ull Z;
        cin>>P;
        if(P==1)
        {
            cin>>X>>Y>>Z; 
            add(Y+1,-Z);
            add(X,Z);
        }
        else if(P==2)
        {
            cin>>X>>Y;
            cout<<sum(Y)-sum(X-1)<<endl;
        }
    }
    return 0; 
}
树状数组区间版
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

int pow_mod(int a,int n,int m)
{
    if(n==0)return 1;
    int x=pow_mod(a,n/2,m);
    long long ans=(long long)x*x%m;
    if(n%2==1)ans=ans*a%m;
    return (int)ans;     
}

int main()
{
    int a,n,m;
    a=3;n=2017;m=5;
    int ans=pow_mod(a,n,m);
    printf("%d",ans);
    return 0;    
}
快速幂
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
//#include<bits/stdc++.h>
using namespace std;
void read(int& x)
{
    int z=1;x=0;char c;c=getchar();
    while(c<'0'||c>'9'){if(c=='-')z=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    x*=z;    
}
struct edge{
    int other,pre,c;
}a[1024];
int last[1024],cnt,dis[1024],in[1024];
bool vis[1024];
void connect(int x,int y,int z)
{
    a[++cnt]=(edge){y,last[x],z};
    last[x]=cnt;    
}
int SPFA(int x,int y)
{
    queue<int> q;
    memset(dis,127,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(in,0,sizeof(in));
    dis[x]=0;
    q.push(x);vis[x]=true;in[x]++;
    while(!q.empty())
    {
        int tmp=q.front();
        q.pop();vis[tmp]=false;
        for(int i=last[tmp];i;i=a[i].pre)
        {
            int to=a[i].other;
            if(dis[tmp]+a[i].c<dis[to])
            {
                dis[to]=dis[tmp]+a[i].c;
                if(!vis[to])
                {
                    vis[to]=true;
                    in[to]++;
                    q.push(to);
//                    if(in[y]>N)exit(0);    
                }    
            }
        }
    }
    return dis[y];
}
int main()
{
    int x,y;
    read(x);read(y);
    connect(1,2,x);
    connect(2,3,y);
    printf("%d
",SPFA(1,3));
    return 0;    
}
A+B(SPFA)
#include<bits/stdc++.h>
using namespace std;
double M[105][105];
int N;
inline bool Gauss()
{
    for(int k=1;k<=N;k++){
        double maxm=-1;int maxi;
        for(int i=k;i<=N;i++)
            if(maxm<fabs(M[i][k]))
                maxm=fabs(M[i][k]),maxi=i;
        if(fabs(maxm)<1e-7)
            return false;
        if(maxi-k)
            for(int j=1;j<=N+1;j++)
                swap(M[maxi][j],M[k][j]);
        double tmp=M[k][k];
        for(int j=1;j<=N+1;j++)
            M[k][j]/=tmp;
        for(int i=k-1?1:2;i<=N;i++){
            if(i==k)continue;
            double tmp=M[i][k];
            for(int j=1;j<=N+1;j++)
                M[i][j]-=tmp*M[k][j];
        }
    }
    return true;
}
int main()
{
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
        for(int j=1;j<=N+1;j++)
            scanf("%lf",&M[i][j]);
    if(Gauss())
        for(int i=1;i<=N;i++)
            printf("%.2lf
",M[i][N+1]);
    else    printf("No Solution");
    return 0;
}
高斯消元
原文地址:https://www.cnblogs.com/Elfish/p/7811431.html