【模板(们)】noip前热身练习(更新中...)

分块+莫队

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
/*分块*/
#include<cmath>
const int N=10;
int pos[N],n,blk;
void fenkuai(){
    scanf("%d",&n);
    blk=(int)(double(n));
    for(int i=1;i<=n;i++) pos[i]=(i-1)/blk+1;
} 
/*莫队*/
int ans=0;
struct qujian{
    int le,ri,ans;
}q[N];
bool cmp(const qujian &a,const qujian &b){
    return pos[a.le]<pos[b.le]||(pos[a.le]==pos[b.le]&&a.ri<b.ri);
}
void update(int pos,int val){
}
void modui(){
    scanf("%d",&n);
    fenkuai();
    for(int i=1;i<=n;i++) scanf("%d%d",&q[i].le,&q[i].ri);
    sort(q+1,q+n+1,cmp);
    int le,ri;
    le=ri=0;
    for(int i=1;i<=n;i++){
        while(ri>q[i].ri){
            update(ri,-1);
            ri--;
        }
        while(ri<q[i].ri){
            update(ri+1,1);
            ri++;
        }
        while(le<q[i].le){
            update(le,-1);
            le++;
        }
        while(le>q[i].le){
            update(le-1,1);
            le--;
        }
        q[i].ans=ans;
    }
    /*...*/
}
分块+莫队

字符串:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10;

/*kmp*/
int lens,lenp,nxt[N];
char s[N],p[N];
void get_nxt(){
    int i=0,j=-1;
    nxt[0]=-1;
    while(i<lenp){
        if(j==-1||p[i]==p[j]){
            i++,j++;
            nxt[i]=j;
        }
        else j=nxt[j];
    }
}
void kmp(){
    int i=0,j=0;
    while(i<lens){
        if(j==-1||s[i]==p[j]){
            i++,j++;
            if(j==lenp){
                /*success*/
                j=nxt[j];
            }
        }
        else j=nxt[j];
    }
}
int main(){
    scanf("%s%s",s,p);
    lens=strlen(s),lenp=strlen(p);
    get_nxt();
    kmp();
    return 0;
}

/*manacher*/
int pal[N];
void fixs(){
    /* "aba" -> "-#a#b#a#+" */
}
void manacher(){
    int id,mx=0;
    for(int i=1;i<=lens;i++){
        if(mx>=i) pal[i]=min(pal[2*id-i],mx-i+1);
        //else pal[i]=1;
        while(s[i+pal[i]]==s[i-pal[i]]) pal[i]++;
        if(pal[i]>mx) mx=pal[i],id=i;
    }
}
int main(){
    scanf("%s",s);
    lens=strlen(s);
    fixs();
    manacher();
    return 0;
}
kmp+manacher

 数据结构

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10;

/*左偏树(大根堆) + 并查集(路径压缩) */
int n,fa[N];
struct node{
    int ls,rs;
    int dis,key;
}tr[N];
int getfa(int x){
    if(fa[x]==x) return x;
    return fa[x]=getfa(fa[x]);
}
int merge(int a,int b){
    if(a==0) return b;
    if(b==0) return a;
    if(tr[a].key<tr[b].key) swap(a,b);
    tr[a].rs=merge(tr[a].rs,b);
    if(tr[tr[a].ls].dis<tr[tr[a].rs].dis) swap(tr[a].ls,tr[a].rs);
    tr[a].dis=tr[tr[a].rs].dis+1;
    return a;
}
int del(int a){
    int tmp=merge(tr[a].ls,tr[a].rs);
    fa[getfa(a)]=tmp;
    fa[fa[getfa(a)]]=tmp;
    return tmp;
}
int main(){
    tr[0].dis=-1,tr[0].key=0;//(small heap)tr[0].key=INF;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&tr[i].key);
    for(int i=1;i<=n;i++) fa[i]=i;
    int q,opt,x,y;
    scanf("%d",&q);
    while(q--){
        scanf("%d",&opt);
        if(opt==0){
            scanf("%d%d",&x,&y);
            if(getfa(x)==getfa(y)) continue;
            int tmp=merge(getfa(x),getfa(y));
            fa[getfa(x)]=fa[getfa(y)]=tmp;
            printf("%d\n",tmp);
        }
        else{
            scanf("%d",&x);
            printf("%d\n",del(getfa(x)));
        }
    }
    return 0;
} 
可并堆(左偏树)
#include<queue>
struct cmp{
    bool operator()(const Type &_a,const Type &_b){
        return _a>_b;//小根堆 
    }
};
priority_queue<Type,vector<Type>,cmp> q;
优先队列STL(堆)

图论

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000+5;
/*dijkstra(spfa)+heap(曾一直以为是spfa)*/
int s=1,n,m,dis[N];
bool exi[N];
int head[N],to[N*2],val[N*2],nxt[N*2],hh=0;
struct cmp{
    bool operator()(const int &a,const int &b){
        return dis[a]>dis[b];
    }
};
priority_queue<int,vector<int>,cmp> q;
void spfa(){
    memset(dis,0x3f,sizeof(dis));
    memset(exi,0,sizeof(exi));
    while(!q.empty()) q.pop();
    dis[s]=0,exi[s]=1;
    q.push(s);
    while(!q.empty()){
        int u=q.top();q.pop();
        exi[u]=0;
        for(int i=head[u];i;i=nxt[i]){
            int v=to[i];
            if(dis[v]>dis[u]+val[i]){
                dis[v]=dis[u]+val[i];
                if(!exi[v]){
                    q.push(v);
                    exi[v]=1;
                }
            }
        }
    }
}
void adde(int a,int b,int v){
    hh++;
    to[hh]=b;
    val[hh]=v;
    nxt[hh]=head[a];
    head[a]=hh;
}
int main(){
    scanf("%d%d",&n,&m);
    int u,v,w;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);
        adde(u,v,w),adde(v,u,w);
    }
    spfa();
    for(int i=1;i<=n;i++) printf("%d ",dis[i]);
    return 0;
}
dijkstra+heap
bool find(int u){
    for(int i=head[u];i;i=nxt[i]){
        int v=to[i];
        if(vis[v]) continue;
        vis[v]=1;
        if(bl[v]==0||find(bl[v])){
            bl[v]=u;
            return true;
        }
    }
    return false;
}
int main(){
    /*...*/
    int cnt=0;
    for(int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));//可用时间戳优化 
        if(find(i)) cnt++;
    }
    /*...*/
} 
匈牙利算法

数论

int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
void exgcd(int a,int b,int &x,int &y){
    if(b==0){
        x=1,y=0;return;
    }
    int x0,y0;
    exgcd(b,a%b,x0,y0);
    x=y0;
    y=x0-(a/b)*y0;
}
gcd+exgcd
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10;

/*线性筛(莫比乌斯函数+欧拉函数)*/
int n;
int prime[N],cntp,phi[N],mui[N];
bool notp[N];
void init(){
    notp[1]=1;
    phi[1]=1,mui[1]=1;
    for(int i=2;i<=n;i++){
        if(!notp[i]){
            prime[++cntp]=i;
            phi[i]=i-1;
            mui[i]=-1;
        }
        for(int j=1;j<=cntp&&i*prime[j]<=n;j++){
            if(i%prime[j]==0){
                phi[i*prime[j]]=phi[i]*prime[j];
                mui[i*prime[j]]=0;
                break;
            }
            phi[i*prime[j]]=phi[i]*(prime[j]-1);
            mui[i*prime[j]]=-mui[i];
            notp[i*prime[j]]=1;
        }
    }
}

/*高斯消元*/
#include<cmath>
const double eps=1e-8;
int n,m;//n项 m方程 
double g[N][N],ans[N];
void gauss(){
    int cnt=0;
    for(int k=1;k<=n;k++){//第k列 
        int j=-1;
        for(int i=cnt+1;i<=m;i++) if(fabs(g[i][k])>eps){
            j=i;break;
        }
        if(j==-1) continue;
        for(int i=1;i<=n+1;i++) swap(g[cnt+1][i],g[j][i]);
        for(j=1;j<=m;j++){
            if(j==cnt+1) continue;//!
            if(fabs(g[j][k])<eps) continue;
            double r=g[j][k]/g[cnt+1][k];
            for(int i=1;i<=n+1;i++)
                g[j][i]-=r*g[cnt+1][i];
        }
        cnt++;
    }
    for(int i=cnt+1;i<=m;i++){
        if(fabs(g[i][n+1])>eps)
            printf("no solution!\n");
    }
    if(cnt<n){
        printf("more than one solution!\n");
        return;
    } 
    for(int i=1;i<=cnt;i++)
        ans[i]=g[i][n+1]/g[i][i];
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n+1;j++) scanf("%lf",&g[i][j]);
    gauss();
    for(int i=1;i<=n;i++) printf("%.2lf ",ans[i]);
    return 0;
}
线性筛(基本积性函数)+高斯消元
Type power(Type a,Type b){
    Type rt=1;
    for(;b;b>>=1,a=a*a%mod) if(b&1) rt=rt*a%mod;
    return rt;
} 
快速幂

 dp

int dfs(int pos,/*int some_ifo,*/bool limit/*,bool zero*/){
    if(pos==0) return 1;
    if((!limit)/*&&(!zero)*/&&f[pos]!=-1) return f[pos];
    int st=limit?k[pos]:9;
    int ans=0;
    for(int i=0;i<=st;i++){
        /*if(some_limit)*/ ans+=dfs(pos-1,/**/,limit&&i==st/*,zero&&i==0*/);
    }
    if((!limit)/*&&(!zero)*/) f[pos]=ans;
    return ans;
}
数位dp

 高精度

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=100000+5;

struct Type{
    int a[N],len;
};
void read(Type &res){
    char ch=0;
    res.a[0]=1,res.len=0;
    while(ch<'0'||ch>'9'){if(ch=='-')res.a[0]=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){res.a[++res.len]=ch-'0';ch=getchar();}
    for(int i=1;i<=res.len/2;i++) swap(res.a[i],res.a[res.len-i+1]);
}
void print(const Type &pr){
    if(pr.a[0]==-1) printf("-");
    for(int i=pr.len;i>=1;i--) printf("%d",pr.a[i]);
}
Type operator +(Type _a,Type _b){
    Type _c;
    _c.len=max(_a.len,_b.len);
    int tmp=0;
    for(int i=1;i<=min(_a.len,_b.len);i++){
        tmp=_a.a[i]+_b.a[i]+tmp;
        _c.a[i]=tmp%10;
        tmp/=10;
    }
    for(int i=min(_a.len,_b.len)+1;i<=_c.len;i++){
        tmp=_a.len>_b.len?_a.a[i]+tmp:_b.a[i]+tmp;
        _c.a[i]=tmp%10;
        tmp/=10;
    }
    if(tmp) _c.a[++_c.len]=tmp;
    return _c;
}
Type operator -(Type _a,Type _b){
    Type _c;
    _c.len=_a.len;
    for(int i=1;i<=_b.len;i++){
        _c.a[i]=_a.a[i]-_b.a[i];
        if(_c.a[i]<0) _c.a[i]+=10,_a.a[i+1]--;
    }
    for(int i=_b.len+1;i<=_a.len;i++) _c.a[i]=_a.a[i];
    while(_c.a[_c.len]==0) _c.len--;
    return _c;
}
Type a,b;
int main(){
    read(a),read(b);
    print(a-b);
    return 0;
}
高精度加减
posted @ 2017-11-06 21:25  LinnBlanc  阅读(224)  评论(0编辑  收藏  举报