c模板区域[未完待续](会不定期的更新哦(有时间就更了))(已经更十一回了哦)(和一些小知识点的总结)//退役前再次更新

       ---转载请征求博主同意

    写这个博客目的就是为了记录下学过的模板方便我这焫鷄复习吧//dalao们绕道

    近期学的:

    (1)来自机房学长jjh大神教的求1~n的所有最小素因数和加上本焫鷄的批注

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>//求1~n的最小质因数
using namespace std;
const int MAXN=1e6+5;
const int LIM=1e6;
int prime[MAXN],mnp[MAXN],cnt=0;
bool vis[MAXN];
int main()
{
    for(int i=2;i<=LIM;i++)
    {
        if(!vis[i])
        {
            mnp[i]=i;//最小质因数
            prime[++cnt]=i;//质因数
        }
        for(int j=1;j<=cnt;j++)
        {
            if(1LL*i*prime[j]>LIM)
                break;
            vis[i*prime[j]]=1;//合数直接标记
            if(i%prime[j]==0)//如果i可以整除以prime[j]
            {
                mnp[i*prime[j]]=mnp[i];//那么这个数的最小质因数就为i的最小质因数
                break;
            }
            else //否则
                mnp[i*prime[j]]=prime[j];//他的最小质因数就为prime[j]
        }
    }
}
ヾ(◍°∇°◍)ノ゙

     (2)比较简单的筛法求素数

void shai(int x)
{
    memset(f,1,sizeof(f));
    for(int i=2;i<=x;i++)
    {
        if(f[i])
        {
            for(int j=i+i;j<=x;j+=i)
            {
                f[j]=false;
            }
        }
    }
    for(int i=2;i<=x;i++)
        if(f[i])
            prime[++len]=i;
}
٩(๑>◡<๑)۶

     (3)反素数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
LL yi[15]={2,3,5,7,11,13,17,19,23,29};
LL n;
LL big,num;
void dfs(LL x,int y,int limit,int z)
{
    if(x>n)
        return;
    if(num<y)
    {
        big=x;
        num=y;
    }
    if(num==y&&big>x)
    {
        big=x;
    }
    LL temp=x;
    for(int i=1;i<=limit;i++)
    {
        temp=temp*yi[z];
        if(temp>n)
            return;
        dfs(temp,y*(i+1),i,z+1);
    }
}
int main()
{
    cin>>n;
    big=0;
    num=0;
    dfs(1,1,50,0);
    cout<<big<<endl;
    return 0;
}
( ̄▽ ̄)/

     (4)来个图论的基本算法Bellman-ford

bool Bellman-ford(int st)
{
    memset(dis,10,sizeof(dis));
    dis[st]=0;
    bool rel=0;
    for(int i=1;i<=n;i++)
    {
        rel=0;
        for(int j=1;j<=len;j++)
        {
            if(dis[a[j].x]+a[j].v<dis[a[j].y])
            {
                dis[a[j].y]=dis[a[j].x]+a[j].v;
                rel=1;
            }
        }
        if(!rel) return 0;
    }
    for(int i=1;i<=len;i++)
    {
        if(dis[a[i].x]+a[i].v<dis[a[i].y])
        {
            return 1;
        }
    }
    return 0; 
}
 ̄へ ̄

     (5)SPFA

void SPFA(int s)        
{
    memset(dis,10,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[s]=0;vis[s]=1;q[1]=s;
    head=0;tail=1;
    while(head<tail)
    {
        int tn=q[++head];
        vis[tn]=0;
        int te=lin[tn];
        for(int j=te;j;j=a[j].next)
        {
            int tmp=a[j].y;
            if(dis[tn]+a[j].v<dis[tmp])
            {
                dis[tmp]=dis[tn]+a[j].v;
                if(!vis[tmp])
                {
                    q[++tail]=tmp;
                    vis[tmp]=1;
                }
            }
        }
    }
}
[]~( ̄▽ ̄)~*

     (6)dijkstra算法

void dijkstra(int st)
{
    for(int i=1;i<=n;i++)
        dis[i]=a[st][i];
    memset(vis,0,sizeof(vis));
    vis[st]=1;dis[st]=0;
    for(int i=1;i<n;i++)
    {
        int minn=9999999;
        int k=0;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]<minn)
            {
                minn=dis[j];
                k=j;
            }
        }
        if(k==0)
            return;
        vis[k]=1;
        for(int j=1;j<=n;j++)
        {
            if((!vis[j])&&(dis[k]+a[k][j]<dis[j]))
                dis[j]=dis[k]+a[k][j];
        }
    }
}
 ̄ω ̄=

     补:堆优化的Dijkstra+邻接表//听说SPFA死了....

 

 1 void dijkstra(int s)
 2 {
 3     priority_queue<P,vector<P>,greater<P> > q;//小根堆因为你要找最短路,若你要找最长路,那么用大根堆。
 4     memset(dis,0,sizeof(dis));
 5     dis[s]=1;
 6     memset(vis,0,sizeof(vis));
 7     q.push(make_pair(dis[s],s));
 8     while(!q.empty())
 9     {
10         P tmp=q.top();
11         q.pop();
12         int x=tmp.second;
13         if(vis[x]) continue;
14         vis[x]=true;
15         for(int i=lin[x],y;i;i=a[i].next)
16         {
17             y=a[i].y;
18             if(dis[y]<dis[x]*a[i].v)
19             {
20                 dis[y]=dis[x]*a[i].v;
21                 if(!vis[y])
22                     q.push(make_pair(dis[y],y));//或者将dis[y]改为-dis[y],这样也就是最长路了
23             }
24         }
25     }
26 }
(◕ᴗ◕✿)

 

 

 

     (7)最小生成树---Prim算法

void Prim(int s)
{
    memset(dis,10,sizeof(dis));
    for(int i=1;i<=n;i++)
        dis[i]=a[s][i];//所有点都不在队列里,除了s
    memset(vis,0,sizeof(vis));
    vis[s]=1; sumn=0;
    for(int i=2;i<=n;i++)
    {
        //寻找现在能到达的边中最短的那条
        int minn=a[0][0],c=0;
        for(int j=1;j<=n;j++)
        {
            if((!vis[j])&&(dis[j]<minn))
            {
                minn=dis[j];
                c=j;
            }
        }
        //c点到达了,最小生成树长度增加
        vis[c]=1;
        sumn+=minn;
        //基于这个点做松弛操作
        for(int j=1;j<=n;j++)
        {
            if((a[c][j]<dis[j])&&(!vis[j]))
                dis[j]=a[c][j];
        }
    }
}
(。・ω・。)

      //未完待续(欲知后事如何请听下回分解)

 第二回更

      (8)先来个网络流(带上Dinic优化)

void insert(int x,int y,int v)
{
    a[++len].y=y; a[len].v=v; a[len].next=lin[x]; lin[x]=len; rev[len]=len+1;
    a[++len].y=x; a[len].v=0; a[len].next=lin[y]; lin[y]=len; rev[len]=len-1;
}
int head,tail;
bool make_level()
{
    head=0,tail=1;
    memset(l,-1,sizeof(l));
    q[1]=0;l[0]=0;
    while(head++<tail)
    {
        int tn=q[head];
        for(int i=lin[tn];i;i=a[i].next)
        {
            if(a[i].v&&l[a[i].y]<0)
            {
                q[++tail]=a[i].y;
                l[a[i].y]=l[tn]+1;
            }
        }
    }
    return l[n]>=0;
}
long long MAX(long long k,long long flow)
{
    if(k==n)
        return flow;
    long long maxflow=0,d=0;
    for(int i=lin[k];i&&maxflow<flow;i=a[i].next)
    {
        if(l[a[i].y]==l[k]+1&&a[i].v)
        {
            if(d=MAX(a[i].y,min(flow-maxflow,a[i].v)))
            {
                maxflow+=d;
                a[i].v-=d;
                a[rev[i]].v+=d;
            }
        }
    }
    if(!maxflow)
        l[k]=-1;
    return maxflow;
}
void Dinic()
{
    long long d;
    while(make_level())
        while(d=MAX(1,INF))
            sum+=d;
}
(๑╹◡╹)ノ"""

      (9)最小生成树---Kruskal算法(中间有并查集的算法详细见(10))

void Kruskal()
{
    for(intt i=1;i<=n;i++)
        father[i]=i;
    sort(a+1,a+m+1,mycmp);
    int cal=0;
    for(int i=1;i<=len;i++)
    {
        int v=getfather(a[i].x);
        int u=getfather(a[i].y);
        if(v!=u)
        {
            father[v]=u;
            if(++cal==n-1)
            {
                cout<<a[i].v<<endl;
                return;
            }
        }
    }
}
!!!∑(゚Д゚ノ)ノ

    (10)并查集

int getfather(int k)//找到祖先
{
    if(father[k]==k)
        return k;
    father[k]=getfather(father[k]);
    return father[k];
}
void merge(int x,int y)//合并
{
    int fx=getfather(x);
    int fy=getfather(y);
    father[fx]=fy;
}
bool judge(int x,int y)//判断是否在一个并查集中
{
    int fx=getfather(x);
    int fy=getfather(y);
    return (fx==fy);
}
ヾ(✿゚▽゚)ノ

    (11)拓扑排序---topsort

void topsort()
{
    int head=0,tail=0;
    for(int i=1;i<=n;i++)
        if(!id[i])
            q[++tail]=i;
    while(head<tail)
    {
        head++;
        for(int i=1;i<=n;i++)
        {
            if(a[q[head]][i])
            {
                id[i]--;
                if(!id[i])
                    q[++tail]=i;
            }
        }
    }
}
_(:з」∠)_

    (补充)topsort(邻接表)

void topsort()
{
    sum[s]=1;
    int head=0,tail=0;
    for(int i=1;i<=n;i++)
        if(!id[i])
            q[++tail]=i;
    while(head<tail)
    {
        head++;
        int tn=q[head];
        for(int i=lin[tn];i;i=a[i].next)
        {
            int tmp=a[i].y;
            id[tmp]--;
            if(!id[tmp])
                q[++tail]=tmp;
        }
    }
}
٩(๑>◡<๑)۶

 

 第三回更

    今天就更新一下字符串的东西吧

   (12)字符串-----KMP

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 1000010
using namespace std;
int p[MAXN];
int main()
{
    string a,b;
    cin>>a>>b;
    int j=-1;
    int la=a.size(),lb=b.size();
    p[0]=-1;
    for(int i=1;i<lb;i++)
    {
        while((j>=0)&&b[i]!=b[j+1])
            j=p[j];
        if(b[j+1]==b[i])
            j++;
        p[i]=j;
    }
    j=-1;
    for(int i=0;i<la;i++)
    {
        while((j>-1)&&b[j+1]!=a[i])
            j=p[j];
        if(b[j+1]==a[i])
            j++;
        if(j==lb-1)
        {
            cout<<i-j+1<<endl;//b在a中出现的位置
            j=p[j];
        }
    }
    return 0;
}
对于之前KMP打错表示抱歉

 

       (13)字符串-----trie树

struct node
{
    char ch;             //本节点的值
    bool endflag;     //是否是某个单词的最后一个字符
    int link[26];         //26个分叉
} tree[600100];
void add(int k,int node)  //k是s的第k个字符,node为当前节点。
{      
    int  chindex=s[k]-‘A’;  //字符的编号
    if (tree[node].link[chindex]==0)   //新开节点
    {
        tree[node].link[chindex]=++len;            
        tree[len].ch=s[k]; 
        tree[len].endflag=false;
    }
    int nexnode=tree[node].link[chindex];  //下一个节点的下标
    if (k==(int)s.size()-1)
    {
        tree[nexnode].endflag=true;
        return;
    }
    add(k+1,nexnode);    
}
bool find(int k, int last,int node)
//k是要查找字符串s的第k个元素
{
    int chindex=s[k]-'a';
    if (tree[node].link[chindex]==0)  return false;
    int nextnode=tree[node].link[chindex];
    if (k==(s.size()-1)) //如果k是最后一个字符
       if (tree[nextnode].endflag)  return true;
        else                   return false;
    return find(k+1,last,nextnode);
}
(▼ヘ▼#)

   (14)字符串------AC自动机

struct node//注:fromjzyz ftp:
{
    int endflag; //是否是某个单词的最后一个字符.小心有多个重复的单词
    int fail;  //失败指针
    int link[26]; //26个分叉
} tree[510100];

char s[1001000];  //用字符数组代替字符串,在1000000 个字符条件下,速度会快一些。
//string s;
int n,m,len=0,ans,slen;
int head,tail,root=0;
int q[510000];
void add(int k,int node)  //k是s的第k个字符,root为当前节点。
{      
    int  chindex=s[k]-'a';
    if (tree[node].link[chindex]==0)   //新开节点
    {
        tree[node].link[chindex]=++len;            
        tree[len].endflag=0; //因为存在有多个相同的单词
        tree[len].fail=root;
    }
    int nexnode=tree[node].link[chindex];
    if (k==slen-1)  //恰好是一个单词的结尾。
    {
        tree[nexnode].endflag++;
        return;
    }
    add(k+1,nexnode);    
}
void init()
{
    scanf("%d\n",&n);
    memset(tree,0,sizeof(tree));
    for (int i=0;i<n;i++)
    {
        scanf("%s",s);     slen=strlen(s);  //因为字符串比较多,用了c语言的字符串读入。
        add(0,root);
    }    
}
void buildac()//生成fail指针,建好AC自动机
//用bfs生成一个层次序列,fail指针肯定往前跳。按层次依次求出fail指针
{
    head=tail=0;
    q[tail]=root;
    while (head<=tail) //bfs广度优先遍历 trie树
    {        
            //if (head>300000) head=0;
             int now=q[head++];//  当前的节点
        int temp; //用来存储临时的fail指针,是tree的下标
        for (int i=0;i<26;i++) //        
            if (tree[now].link[i])  //求link[i].fail指针                
            {
                int nextnode=tree[now].link[i];
                if (now!=root)//如果是根,那么fail肯定是root
                {
                    temp=tree[now].fail;
                    while (!tree[temp].link[i] && temp)//找不到与 link[i]匹配的前缀  且没有退到根                
                        temp=tree[temp].fail; //继续向上退
                        tree[nextnode].fail=tree[temp].link[i];    
                }
                       
                       q[++tail]=nextnode;  //让这个子节点进队。
            }                
    }
}

void find()
{   
      ans=0;
    int now=root;
    scanf("%s",s);          len=strlen(s);  //这里用的也是c语言的字符。
    for(int i=0;i<len;i++)
    {
        int chindex=s[i]-'a';
        while( !tree[now].link[chindex] && now!=root)//如果找不到,往回返        
            now=tree[now].fail;
        now=tree[now].link[chindex];//下一层传递。
        int temp=now;//如果找到某个单词
        while(temp!=root&& tree[temp].endflag>-1 ) //如果找到某个单词,累加到结果
        {
            ans+= tree[temp].endflag;
            tree[temp].endflag=-1;
            temp=tree[temp].fail;
        }
    }
    printf("%d",ans);
}

int main()
{
     freopen("ac.in","r",stdin);
     freopen("ac.out","w",stdout); 
     //scanf("%d",&m);
     //while (m--)
     {
        init();
        buildac();
        find(); 
     }
     fclose(stdin);fclose(stdout);
     return 0; 
}
( • ̀ω•́ )✧

 第四回更

   (15)hash表  

const int maxprime=2323237;
const int step=7;
struct shaodw
{
    int v,num;
}hash[maxprime+5];
int n,x;
int find(int x)
{
    int temp=x%maxprime;
    while(hash[temp].v!=0&&hash[temp].v!=x)
    {
        temp+=step;
        if(temp>=maxprime)
            temp-=maxprime;
    }
    return temp;
}
void insert(int x)
{
    int now=find(x);
    if(hash[now].v==x)
        hash[now].num++;
    else
    {
        hash[now].v=x;
        hash[now].num=1;
    }
}
int main()
{
    memset(hash,0,sizeof(hash));
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x;
        insert(x);
    }
    return 0;
}
٩(๑❛ᴗ❛๑)۶

   (16)hash--字符串

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
const unsigned int seed=131;
#define mod 2323237
int n,len=0,lin[300n0010];
char c[210];
struct node{
    int ne;
    char ch[210];
}hash[50010];

unsigned int getkey(){
    int len=strlen(c);
    unsigned int key=0;
    for (int i=0;i<len;i++)
        key=key*seed+c[i];
    return (key&0x7fffffff)%mod;
}

void add(int key)
{hash[++len].ne=lin[key];lin[key]=len;strcpy(hash[len].ch,c);}

bool find(){
    int key=getkey();
    for (int i=lin[key];i;i=hash[i].ne)
        if (strcmp(hash[i].ch,c)==0)    return false;
    add(key);
    return true;
}

int main(){
    //freopen("add.in 

","r",stdin);
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        scanf("%s",c);
        if (!find())    printf("%d\n",i);
    }
    return 0;
}
(╬ ̄皿 ̄)

  (17)莫队模板//例题:小Z的袜子

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
inline long long read()
{
    long long x=0,f=1;
    char ch=getchar();
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
long long gcd(long long a,long long b)
{return b==0?a:gcd(b,a%b);}
struct shadow
{
    long long l,r,id;
}a[300000],S[300000];
long long s[300000],cnt[300000];
long long d[300000],mo[300000];
bool mycmp(shadow x,shadow y)
{
    if(x.l!=y.l)
        return x.l<y.l;
    return x.r<y.r;
}
bool cmp(shadow x,shadow y)
{return x.r>y.r;}
bool dmp(shadow x,shadow y)
{return x.id<y.id;}
long long ans=0;
int len=0;
void simp(long long a,long long b,long long id)
{
    long long t=gcd(a,b);
    a/=t;b/=t;
    S[++len].l=a;
    S[len].r=b;
    S[len].id=id;
}
long long str(long long x)
{return x*x;}
int main()
{
    //freopen("hose.in","r",stdin);
    //freopen("hose.out","w",stdout);
    long long n,m;
    n=read();m=read();
    for(int i=1;i<=n;i++)
    {
        s[i]=read();
    }
    for(int i=1;i<=m;i++)
    {
        a[i].l=read();
        a[i].r=read();
        a[i].id=i;
    }
    sort(a+1,a+1+m,mycmp);
    int qw=int(sqrt(1.0*m));
    int ii;
    for(ii=qw;ii<=m;ii+=qw)
    {
        sort(a+ii-qw+1,a+1+ii,cmp);
    }
    if(ii!=m)
        sort(a+ii+1,a+ii+m+1,cmp);
    long long l=1;
    long long r=0;
    for(int i=1;i<=m;i++)
    {
        while(r<a[i].r)
        {
            r++;
            ans-=str(cnt[s[r]]);
            cnt[s[r]]++;
            ans+=str(cnt[s[r]]);
        }
        while(r>a[i].r)
        {
            ans-=str(cnt[s[r]]);
            cnt[s[r]]--;
            ans+=str(cnt[s[r]]);
            r--;
        }
        while(l>a[i].l)
        {
            l--;
            ans-=str(cnt[s[l]]);
            cnt[s[l]]++;
            ans+=str(cnt[s[l]]);
        }
        while(l<a[i].l)
        {
            ans-=str(cnt[s[l]]);
            cnt[s[l]]--;
            ans+=str(cnt[s[l]]);
            l++;
        }
        long long M=(long long)ans-(a[i].r-a[i].l+1);
        long long N=(long long)(a[i].r-a[i].l+1)*(a[i].r-a[i].l);
        simp(M,N,a[i].id);
    }
    sort(S+1,S+1+m,dmp);
    for(int i=1;i<=m;i++)
    {
        cout<<S[i].l<<'/'<<S[i].r<<endl;
    }
    return 0;
}
(*@ο@*)

   (18)LCA模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read()
{
    char ch=getchar();
    int x=0,f=1;
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
const int MAXN=100100;
struct shadow
{
    int y,next;
}a[MAXN*4];
int lin[MAXN*4];
int len=0;
void insert(int x,int y)
{
    a[++len].next=lin[x];
    lin[x]=len;
    a[len].y=y;
}
int dep[MAXN*4];
int f[MAXN*4],size[MAXN*4],son[MAXN*4],top[MAXN*4];
void dfs1(int x)
{
    dep[x]=dep[f[x]]+1;
    size[x]=1;
    for(int i=lin[x];i;i=a[i].next)
    {
        if(a[i].y!=f[x]&&!f[a[i].y])
        {
            f[a[i].y]=x;
            dfs1(a[i].y);
            size[x]+=size[a[i].y];
            if(size[son[x]]<size[a[i].y])
                son[x]=a[i].y;
        }
    }
}
void dfs2(int x)
{
    if(x==son[f[x]])
        top[x]=top[f[x]];
    else
        top[x]=x;
    for(int i=lin[x];i;i=a[i].next)
        if(f[a[i].y]==x)
            dfs2(a[i].y);
}
int ask(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]>dep[top[y]])
            x=f[top[x]];
        else
            y=f[top[y]];
    }
    if(dep[x]<dep[y])
        return x;
    else
        return y;
}
int main()
{
    int n,m;
    n=read();m=read();
    for(int i=1;i<n;i++)
    {
        int x,y;
        x=read();y=read();
        insert(x,y);
        insert(y,x);
    }
    dfs1(1);
    dfs2(1);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        x=read();y=read();
        int ans=ask(x,y);
        cout<<ans<<endl;
    }
    return 0;
}
(๑*◡*๑)

    (19)归并排序

int a[100002],c[100002];
void worksort(int l,int r)
{
    int cnt=0;//逆序对个数
    int mid,tmp,i,j;
    if(r>l+1)
    {
        mid=(l+r)/2;
        worksort(l,mid-1);
        worksort(mid,r);
        tmp=1;
        for(i=l,j=mid;i<=mid-1&&j<=r;)
        {
            if(a[i]>a[j])
            {
                c[tmp++]=a[j];
                cnt+=mid-i;
            }
            else
                c[tmp++]=a[i++];
        }
        if(j<=r)
            for(;j<=r;j++)
                c[tmp++]=a[j];
        else
            for(;i<=mid-1;i++)
                c[tmp++]=a[i];
        for(i=l;i<=r;i++)
            a[i]=c[i];
    }
    else
    {
        if(l+1==r)
            if(a[l]>a[r])
            {
                swap(a[l],a[r]);
                cnt++;
            }
    }
}
(ノ`Д)ノ

 第五会更

   (20)trajan

void trajan(int x)
{
    low[x]=dfn[x]=++num;
    s.push(x);
    for(int i=lin[x];i;i=a[i].next)
    {
        int g=a[i].y;
        if(!dfn[g])
        {
            trajan(g);
            low[x]=min(low[x],low[g]);
        }
        else if(!vis[g])
            low[x]=min(low[x],dfn[g]);
    }
    if(low[x]==dfn[x])
    {
        sum++;
        while(1)
        {
            int t=s.top();
            s.pop();
            vis[t]=sum;
            if(t==x)
                break;
        }
    }
}
(꒪Д꒪)ノ

   (21)今天学到了一个新东西..因为我们oj限制栈的大小,所以得用一个东西把限制的大小调大(NOIP和CCF这些正规的比赛都不会限制大小但....省选会)

    int __size__ = 20 << 20; // 20MB
    char *__p__ = (char*)malloc(__size__) + __size__;
    __asm__("movl %0, %%esp\n" :: "r"(__p__));
(。◕ˇ∀ˇ◕)

    (22)Kosaraju算法

void DFS_T(int u)
{
    int i,v;
    if(used[u])return ;
    used[u]=1;id[u]=scc;
    for(i=q[u];i!=-1;i=Tedge[i].pre)
    {
        v=Tedge[i].d;
        if(!used[v])
        DFS_T(v);
    }
}
void DFS(int v){
    int i,u;
    if(used[v])return ;
    used[v]=1;
    for(i=p[v];i!=-1;i=edge[i].pre)
    {
        u=edge[i].d;
        if(!used[u])DFS(u);
    }
    order[++num]=v;
}
int Kosaraju()
{
    int i,j,k,v,u;
    memset(used,0,sizeof(used));num=0;
    for(i=1;i<=n;++i)
        if(!used[i])
            DFS(i);
    memset(used,0,sizeof(used));
    memset(id,0,sizeof(id));scc=0;
    for(i=num;i>=1;--i)
         if(!used[order[i]])
             scc++,DFS_T(order[i]);
}                    
︿( ̄︶ ̄)︿

    第六会更

  (23)费用流模板

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iomanip>
using namespace std;
const int maxn=10100;
const int oo=202116108;  //memset 12 的值

struct node
{
    int y,v,flow,next; //v是费用,flow是流量
    int reverse;  //反向变的编号。
}edge[5*maxn];  // 邻接表的 边数组
int link[maxn];  //邻接表的 点数组
int q[1000010];
int dis[maxn],tot=0;
int temp,ans=0;
int n,m,s,t; //s是源点, t是汇点。
bool vis[maxn];
int lastnode[maxn],lastedge[maxn]; //记录增广路径用。
void add (int x,int y,int z,int c,int re)
{
    edge[++tot].y=y; edge[tot].v=-z; edge[tot].flow=c;
    edge[tot].reverse=tot+re;
    edge[tot].next=link[x]; link[x]=tot;
}
void init()
{
    scanf("%d %d", &n,&m);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            int xx=(i-1)*m+j; //二维压一维。xx表示第i行第j列点的编号
            int yy=2*xx;  xx=yy-1;
            scanf("%d" ,&temp);
            add(xx,yy,temp,1,1);  //正向边
            add(yy,xx,-temp,0,-1); //反向边,退流的话把相关的费用返还。
            if (j<m) //当前点右方有点
            {
                add(yy,yy+1,0,1,1); //右方连一个费用为0,流量为1的边。
                add(yy+1,yy,0,0,-1); //逆向边的流量初值为0;
            }
            if (i<n)
            {
                add(yy,yy+2*m-1,0,1,1); //下方的边费用也是1.
                add(yy+2*m-1,yy,0,0,-1);
            }
            s=1; t=n*m*2-1;
            edge[s].flow=2; //源点出去的流量只为2.限制了总体流量。
        }
}
bool spfa()
{
    memset(vis,0,sizeof(vis));
    memset(dis,12,sizeof(dis));
    dis[1]=0; vis[1]=true;
    q[0]=1; 
    int head=0,tail=0;
    while (head<=tail) //队列不为空
    {
        int tn=q[head++];
        for (int te=link[tn];te;te=edge[te].next)  //枚举边
        {
            int ty=edge[te].y;
            if (edge[te].flow &&(dis[tn]+edge[te].v<dis[ty]))  //首先的有流量再判断费用
            {
                if (!vis[ty])  //不在队列里。
                {
                    q[++tail]=ty;
                    vis[ty]=true;
                }
                dis[ty]=dis[tn]+edge[te].v;
                lastnode[ty]=tn; lastedge[ty]=te;   //增广路的记录,用于下面的增广。
            }
        }
        vis[tn]=false;
    }
    return(dis[t]!=oo); //如果到t的最短距离存在,表明存在一个费用最小的增广路。
}
void agu()  //按照增广路径进行流量增减
{
    int delta=oo;
    for (int now=t;now!=s;now=lastnode[now])
        if (edge[lastedge[now]].flow<delta )   //找出流量
            delta=edge[lastedge[now]].flow;
    for (int now=t;now!=s;now=lastnode[now])  //更新流量
    {
        int te=lastedge[now];
        edge[te].flow-=delta;
        int re=edge[te].reverse;
        edge[re].flow+=delta;
        ans+=delta*(-edge[te].v);        
    }
}
void costflow()
{
    while (spfa())
        agu();
    cout<<ans<<endl;
}
int main()
{
    freopen("message.in","r",stdin);
    freopen("message.out","w",stdout);
      init();
      costflow();
    fclose(stdin);fclose(stdout);
    return 0; 
}
ヽ(゚∀゚)メ(゚∀゚)ノ

    (24)输出n位小数

cout<<setiosflags(ios::fixed)<<setprecision(n);//n为你要输出小数的位数记得加上头文件#include<iomanip>

   (25)二分图------邻接矩阵(DFS)

bool find(int x)
{
    for(int i=1;i<=m;i++)
    {
        if(a[x][i]&&!vis[i])
        {
            vis[i]=1;
            if(!id[i]||find(id[i]))
            {
                id[i]=x;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        bool flag=find(i);
        if(flag)
        {
            ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}
(๑╹◡╹)ノ"""

     //vector的一些用法

push_back   在数组的最后添加一个数据
pop_back    去掉数组的最后一个数据 
at                得到编号位置的数据
size           当前使用数据的大小
erase         删除指针指向的数据项
clear          清空当前的vector
empty        判断vector是否为空
swap         与另一个vector交换数据
begin         返回第一个元素
end            返回最后一个元素
//头文件  #include<vector>

     //位运算一些基本技巧

 1 x&y   表示在x和y的二进制中如果同位上x和y的数都为一则为一否则为0;如下
 2             10010110
 3         &   01011010
 4 -------------------------
 5             00010010
 6 x|y  表示在x和y的二进制中如果同为上的x和y的数有一个为一的话那么就为一否则为0,如下:
 7             1011011
 8         |   0110001
 9 ------------------------
10             1111011
11 x^y(异或) 表示x和y的二进制中如果同位上一个为1,一个为0那么为1,都为1或都为0则为0 如下:
12             1100101
13          ^  0111011
14 -------------------------
15             1011110
16 ~x 则表示把x二进制中所有为0变1,1变0,取反的时候是无符号的

     (27)dfs序递归版

void dfs(int now,int father)
{
    l[now]=++cnt;
    for(int i=linkk[now];i;i=e[i].next)
    {
        int tn=e[i].y;
        if(tn==father)
            continue;
        dfs(tn,now);
    }
    r[now]=cnt;
}
✧(≖ ◡ ≖✿

    (28)dfs序非递归版

void Shadow()
{
    memset(id,0,sizeof(id));
    memset(l,0,sizeof(l));
    memset(r,0,sizeof(r));
    for(int i=1;i<=n;i++)
        id[i]=linkk[i];
    stack[++top]=1,stack[0]=0;
    while(top)
    {
        int now=stack[top];
        if(!l[now])
            l[now]=++cnt,dep[now]=dep[stack[top-1]]+1,v[now]=v[stack[top-1]]+v[now];
        if(id[now])
        {
            int edgee=id[now];
            id[now]=e[edgee].next;
            if(e[edgee].y==stack[top-1])
                continue;
            stack[++top]=e[edgee].y;
        }
        else
            r[stack[top--]]=cnt;
    }
}
\\\٩('ω')و////

    (29)树链剖分+线段树(ojP2047,soj375)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 101000
using namespace std;
inline int read()
{
    char ch=getchar();
    int x=0,f=1;
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
struct shadow
{
    int y,next;
}a[MAXN*2];
int d[MAXN][3];
int n,len=0,lin[MAXN*2];
void insert(int x,int y)
{
    a[++len].y=y;
    a[len].next=lin[x];
    lin[x]=len;
}
int siz[MAXN],top[MAXN],fa[MAXN],w[MAXN];
int son[MAXN],tree[MAXN],dep[MAXN],num=0;
void dfs(int x)
{
    siz[x]=1;son[x]=0;
    for(int i=lin[x];i;i=a[i].next)
    {
        int tmp=a[i].y;
        if(tmp!=fa[x])
        {
            fa[tmp]=x;
            dep[tmp]=dep[x]+1;
            dfs(tmp);
            if(siz[tmp]>siz[son[x]])
                son[x]=tmp;
            siz[x]+=siz[tmp];
        }
    }
}
void build(int x,int y)
{
    w[x]=++num; top[x]=y;
    if(son[x]) 
        build(son[x],top[x]);
    for(int i=lin[x];i;i=a[i].next)
    {
        int tmp=a[i].y;
        if(tmp!=son[x] &&tmp!=fa[x])
            build(tmp,tmp);
    }
}
void updata(int root,int lo,int hi,int g,int x)
{
    if(g>hi||lo>g) return;
    if(lo==hi)
    {
        tree[root]=x;
        return ;    
    }
    int mid=(hi+lo)/2,ls=root<<1,rs=root<<1|1;
    updata(ls,lo,mid,g,x);
    updata(rs,mid+1,hi,g,x);
    tree[root]=max(tree[ls],tree[rs]);
}
int search(int root,int lo,int hi,int l,int r)
{
    if(l>hi||r<lo) return 0;
    if(l<=lo&&hi<=r)
        return tree[root];
    int mid=(lo+hi)/2,ls=root<<1,rs=root<<1|1;
    int templ=search(ls,lo,mid,l,r);
    int tempr=search(rs,mid+1,hi,l,r);
    return max(templ,tempr);
}
inline int find(int x,int y)
{
    int f1=top[x],f2=top[y],tmp=0;
    while(f1!=f2)
    {
        if(dep[f1]<dep[f2])
            swap(f1,f2),swap(x,y);
        tmp=max(tmp,search(1,1,num,w[f1],w[x]));
        x=fa[f1];f1=top[x];
    }
    if(x==y) return tmp;
    if(dep[x]>dep[y]) swap(x,y);
    return max(tmp,search(1,1,num,w[son[x]],w[y]));
}
char ch[MAXN];
inline void r()
{
    ch[0]=' ';
    while(ch[0]<'C'||ch[0]>'Q')
        scanf("%s",ch);
}
int main()
{
    int __size__ = 20 << 20; // 20MB
 char *__p__ = (char*)malloc(__size__) + __size__;
 __asm__("movl %0, %%esp\n" :: "r"(__p__));
    int t=read();
    for(int i=1;i<=t;i++)
    {
        memset(siz,0,sizeof(siz));
        memset(lin,0,sizeof(lin));
        memset(tree,0,sizeof(tree));
        n=read();
        int oo=(n+1)/2;
        for(int j=1;j<n;j++)
        {
            int x=read(),y=read(),z=read();
            d[j][0]=x;d[j][1]=y;d[j][2]=z;
            insert(x,y);insert(y,x);
        }
        dfs(oo);
        build(oo,oo);
        for(int i=1;i<n;i++)
        {
            if(dep[d[i][0]]>dep[d[i][1]])
                swap(d[i][0],d[i][1]);
            updata(1,1,num,w[d[i][1]],d[i][2]);
        }
        for(r();ch[0]!='D';r())
        {
            int q=read(),h=read();
            if(ch[0]=='Q')
                cout<<find(q,h)<<endl;
            else
                updata(1,1,num,w[d[q][1]],h);
        }
    }
    return 0;
}
(o°ω°o)

            //连个stl全排序的函数

next_permutation(a+1,a+1+n);//排1,2,3,4....n
prev_permutation(a+1,a+1+n);//排n-1,n-2,n-3.....1

    (30)next_premutation的代码实现

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int a[100000];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=m;i++)//一共调整m次
    {//以下为核心代码
        int j,k,p,q,temp;
        j=n-1;
        while((j>0)&&(a[j]>a[j+1])) 
            j--;
        if(j>0)
        {
            k=n;
            while(a[k]<a[j])
                k--;
            swap(a[j],a[k]);
            for(p=j+1,q=n;p<q;p++,q--)
                swap(a[p],a[q]);
        }
    }
    for(int i=1;i<=n;i++)
        cout<<a[i]<<' ';
    cout<<endl;
    return 0;
}
꒰╬•᷅д•᷄╬꒱

     (31)[noip2006普及]Jam的计数法(解此类问题的代码,由上一组合产生下一组合)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
char ch[26];
int main()
{
    int l,r,w;
    cin>>l>>r>>w;
    cin>>ch;
    r=r+'a'-1;
    for(int i=1;i<=5;i++)
    {
        int j=w-1;
        while((j>=0)&&(ch[j]==r-(w-1-j))) j--;
        if(j<0) break;
        ch[j]++;
        for(int k=j+1;k<w;k++)
            ch[k]=ch[k-1]+1;
        for(int j=0;j<=w;j++)
            cout<<ch[j];
        cout<<endl;
    }
    return 0;
}
( ̄3 ̄)a

         //带权中位数,例题:OJ1627

给出了若干个排列在一条直线上的点,每个点有一个权值,比如说货物量、人数什么的,然后让我们找出使所有点的货物、人集合到一个点的总代价最小的位置//带权中位数就是求这个东西的
网上看证明一大堆,大概来说,打个比方,现在有一列的东西,每个东西都有一个权值。
让你在这一列中选一个地方使所有物品到这个位置的距离×权值最小。然后你就可以将这列东西分为两部分,先算出权值和的平均数。
然后一个从前向后记录前缀和,当这个前缀和大于权值平均数时,这样这列物品就被分为了两部分。
左半边的所有权值加上中间这个物品的权值大于右边,右边的总权值加上中间的权值大于左边,那么这个点的权值就是带权中位数//大概就是个这个东西

    //oj1627代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
inline int read()
{
    char ch=getchar();
    int x=0,f=1;
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
struct shadow
{
    int x,y,v;
}a[101000];
bool mycmp(shadow x,shadow y)
{return x.x<y.x;}
bool emp(shadow x,shadow y)
{return x.y<y.y;}
int main()
{
    int n=read(),sum=0;
    for(int i=1;i<=n;i++)
    {
        a[i].x=read();a[i].y=read();
        int p=read(),k=read();
        a[i].v=p*k;
        sum+=a[i].v;
    }
    sum=(sum+1)/2;
    sort(a+1,a+1+n,mycmp);
    int ansx=0,ansy=0,tmp=0;
    for(int i=1;i<=n;i++)
    {
        tmp+=a[i].v;
        if(tmp>=sum)
        {
            ansx=a[i].x;
            break;
        }
    }
    tmp=0;
    sort(a+1,a+1+n,emp);
    for(int i=1;i<=n;i++)
    {
        tmp+=a[i].v;
        if(tmp>=sum)
        {
            ansy=a[i].y;
            break;
        }
    }
    cout<<ansx<<' '<<ansy<<endl;
    return 0;
}
٩(๑❛ᴗ❛๑)۶

    (32)dfs序

void dfs(int p)
{
    f[p]=true;
    in[p]=++tot;
    for(int i=lin[p];i;i=e[i].next)
    {
        if(!f[e[i].y])
        dfs(e[i].y);
    }
    out[p]=tot;
}
(>ω・* )ノ

     (33)2-sat模板//例题:bzoj1823满汉全席

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 3100
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int get()
{
    int x;
    char c=getchar();
    while(c!='m'&&c!='h')
        c=getchar();
    if(c=='m') x=read()*2;
    else x=read()*2-1;
    return x;
}
struct shadow
{
    int y,next;
}a[MAXN*2];
int lin[MAXN],dfn[MAXN],low[MAXN],q[MAXN],b[MAXN];
int len=0,ind=0,l=0,sum=0;
bool vis[MAXN];
void insert(int x,int y)
{
    a[++len].y=y;
    a[len].next=lin[x];
    lin[x]=len;
}
void trajan(int x)
{
    low[x]=dfn[x]=++ind;
    vis[x]=1;q[++l]=x;
    for(int i=lin[x];i;i=a[i].next)
        if(!dfn[a[i].y])
        {
            trajan(a[i].y);
            low[x]=min(low[x],low[a[i].y]);
        }
        else if(vis[a[i].y])
            low[x]=min(low[x],dfn[a[i].y]);
    if(low[x]==dfn[x])
    {
        sum++;
        int now=0;
        while(now!=x)
        {
            now=q[l--];
            b[now]=sum;
            vis[now]=0;
        }
    }
}
int main()
{
    int k=read();
    for(int i=1;i<=k;i++)
    {
        ind=l=sum=len=0;
        int n=read(),m=read();
        memset(lin,0,sizeof(lin));
        memset(dfn,0,sizeof(dfn));
        int x,y,X,Y;
        for(int i=1;i<=m;i++)
        {
            x=get();y=get();
            if(x%2==0) X=x--;
            else       X=x++;
            if(y%2==0) Y=y--;
            else       Y=y++;
            insert(X,y);
            insert(Y,x);
        }
        bool f=0;
        for(int i=1;i<=n*2;i++)
            if(!dfn[i])
                trajan(i);
        for(int i=1;i<=n;i++)
            if(b[i*2]==b[i*2-1])
            {
                cout<<"BAD"<<endl;
                f=1;
                break;
            }
        if(!f)
            cout<<"GOOD"<<endl;
    }
    return 0;
}
〒▽〒

   (34)高斯消元

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
double a[1100][1100];
int n;
void Gauss()
{
    int now=1,x,y;
    double t;
    for(int i=1;i<=n;i++)
    {
        for(x=now;x<=n;x++)
            if(a[x][i]!=0)
                break;
        if(x>n) continue;
        if(x!=now)
            for(int j=1;j<=n+1;j++)
                swap(a[x][j],a[now][j]);
        t=a[now][i];
        for(int j=1;j<=n+1;j++)
            a[now][j]/=t;
        for(int j=1;j<=n;j++)
            if(j!=now)
            {
                t=a[j][i];
                for(int k=1;k<=n+1;k++)
                    a[j][k]-=t*a[now][k];
            }
            now++;
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n+1;j++)
            cin>>a[i][j];
    Gauss();
    for(int i=1;i<=n;i++)
        cout<<(int)round(a[i][n+1])<<endl;
    return 0;
}
。◕ᴗ◕。

   (35)矩阵乘法-------斐波那契数列第n项

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<ctime>
#define K 10000
#define LL long long
using namespace std;
inline int read()
{
    char ch=getchar();
    int x=0,f=1;
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
struct Matrix
{
    LL m[2][2];
};
Matrix A=
{
    1,1,
    1,0
};
Matrix B=
{
    1,0,
    0,1
};
Matrix multi(Matrix a,Matrix b)
{
    Matrix c;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            c.m[i][j]=0;
            for(int k=0;k<2;k++)
                c.m[i][j]+=a.m[i][k]*b.m[k][j]%K;
            c.m[i][j]%=K;
        }
    }
    return c;
}
Matrix power(Matrix A,int k)
{
    Matrix ans=B,p=A;
    while(k)
    {
        if(k&1)
        {
            ans=multi(ans,p);
            k--;
        }
        k>>=1;
        p=multi(p,p);
    }
    return ans;
}
int main()
{
    for(;;)
    {
        LL k;
        k=read();
        if(k==-1)
            break;
        if(k==0)
        {
            cout<<0<<endl;
            continue;
        }
        Matrix ans=power(A,k-1);
        cout<<ans.m[0][0]<<endl;
    }
    return 0;
}
❥(ゝω・✿ฺ)

   (36)莫比乌斯函数

void mobius()
{
    memset(vis,0,sizeof(vis));
    mu[1]=1;
    for(int i=2;i<=N;i++)
    {
        if(!vis[i])
        {
            mu[i]=-1;
            prime[++l]=i;
        }
        for(int j=1;j<=N;j++)
        {
            if(i*prime[j]>N)
                break;
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                mu[i*prime[j]]=0;
                break;
            }
            mu[i*prime[j]]=-mu[i];
        }
    }
}
(*^-^*)

   (37)中国剩余定理//互质版

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
long long n,x,y,M=1;
void exgcd(long long a,long long b,long long &x,long long &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return;
    }
    exgcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-a/b*y;
}
long long a[1100],b[1100];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i]>>b[i];
        M*=a[i];
    }
    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        long long x,y,Mi=M/a[i];
        exgcd(Mi,a[i],x,y);
        ans=((ans+Mi*x*b[i])%M+M)%M;
    }
    cout<<ans<<endl;
    return 0;
}
o( ̄▽ ̄)d

  (38)中国剩余定理//非互质版

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define MAXN 101000
using namespace std;
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
ll m[MAXN],q[MAXN];
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
    if(b==0)
    {
        d=a;
        x=1;
        y=0;
        return ;
    }
    exgcd(b,a%b,d,x,y);
    int t=x;
    x=y;
    y=t-a/b*y;
}
ll M;
int k;
ll China()
{
    ll A=q[1],x,y;
    M=m[1];
    for(int i=2;i<=k;i++)
    {
        ll da=q[i]-A,d;
        exgcd(M,m[i],d,x,y);
        if(da%d) return -1;
        ll t=m[i]/d;
        x*=da/d;
        x=(x%t+t)%t;
        A+=x*M;
        M=M*m[i]/d;
        A=(A+M)%M;
    }
    return A;
}
int main()
{
    while(~scanf("%d",&k))
    {
        for(int i=1;i<=k;i++)
            m[i]=read(),q[i]=read();
        cout<<China()<<endl;
    }
    return 0;
}
T^T//poj2891

   (39)求杨辉三角第n行

1 c[0]=1;
2 for(int i=1;i<=n;i++)//K为摸数,n为第n行
3 {    
4     c[i]=(c[i-1]*(n-i+1)/i)%K;
5     c[i]%=K;
6 }

   (40)第二类Stirling数模板//ojp1807例题==模板题

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int a[15][15];//当元素超过20的时候记住用long long
int main()
{
    int n,r;
    cin>>n>>r;
    memset(a,0,sizeof(a));
    for(int i=1;i<15;i++)
        a[i][1]=1;
    for(int i=2;i<15;i++)
    {
        for(int j=1;j<=i;j++)
        {
            a[i][j]=a[i-1][j-1]+j*a[i-1][j];
        }
    }
    long long ans=1;
    for(int i=1;i<=r;i++)
        ans*=i;
    cout<<a[n][r]*ans<<endl;
    return 0;
}
(ˇˍˇ) 想~

   (41)错位排序

for(int i=2;i<=n;i++)
{
    f[i]=f[i-1]+f[i-2];
    f[i]=f[i]*(i-1);
}    

  

  (42)错位排序-----高精度版//例题HAOI2016 T2放棋子

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 struct shadow
 8 {
 9     int len;
10     int num[1000];
11 }a[210],c;
12 void mul(int x,int y)
13 {
14     memset(c.num,0,sizeof(c.num));
15     c.len=0;
16     int len=a[y].len;
17     for(int i=1;i<=len;i++)
18     {
19         c.num[i]+=(a[y].num[i]*x);
20         if(c.num[i]>=10)
21         {
22             c.num[i+1]=c.num[i]/10;
23             c.num[i]%=10;
24         }
25     }
26     len++;
27     while(c.num[len]>0)
28     {
29         c.num[len+1]=c.num[len]/10;
30         c.num[len++]%=10;
31     }
32     c.len=--len;
33     a[y].len=c.len;
34     for(int i=1;i<=a[y].len;i++)
35         a[y].num[i]=c.num[i];
36 }
37 void add(int x,int y)
38 {
39     memset(c.num,0,sizeof(c));
40     int len=a[x].len;
41     if(a[y].len>a[x].len)
42         len=a[y].len;
43     for(int i=1;i<=len;i++)
44     {
45         c.num[i]+=a[x].num[i]+a[y].num[i];
46         if(c.num[i]>=10)
47         {
48             c.num[i+1]++;
49             c.num[i]=c.num[i]-10;
50         }
51     }
52     if(c.num[len+1]>0)
53         len++;
54     c.len=len;
55     a[x+1].len=len;
56     for(int i=1;i<=len;i++)
57         a[x+1].num[i]=c.num[i];
58 }
59 int main()
60 {
61     int n;
62     cin>>n;
63     a[0].num[1]=1;a[0].len=1;
64     a[1].num[1]=0;a[1].len=0;
65     for(int i=2;i<=n;i++)
66     {
67         add(i-1,i-2);
68         mul(i-1,i);
69     }
70     for(int i=a[n].len;i>=1;i--)
71         cout<<a[n].num[i];
72     cout<<endl;
73     return 0;
74 }
\(^o^)/~

  (43)高精度乘以单精度

 1 void mul(int x)
 2 {
 3     memset(c.num,0,sizeof(c.num));
 4     c.len=0;
 5     int len=a.len;
 6     for(int i=1;i<=len;i++)
 7     {
 8         c.num[i]+=(a.num[i]*x);
 9         if(c.num[i]>=10)
10         {
11             c.num[i+1]=c.num[i]/10;
12             c.num[i]%=10;
13         }
14     }
15     len++;
16     while(c.num[len]>0)
17     {
18         c.num[len+1]=c.num[len]/10;
19         c.num[len++]%=10;
20     }
21     c.len=--len;
22 }

  (44)高精度乘以高精度

 1 #include<iostream> 
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cstring>
 6 #include<cstdio>
 7 using namespace std;
 8 struct bignum
 9 {
10     int len;
11     int num[1000];
12 }a,b,c;
13 void big(string s,bignum&c)
14 {
15     int h;
16     reverse(s.begin(),s.end());
17     h=s.size();
18     for(int i=0;i<h;i++)
19         c.num[i+1]=int(s[i]-'0');
20     c.len=s.size();
21 }
22 void init()
23 {
24     string s1,s2;
25     cin>>s1>>s2;
26     big(s1,a);
27     big(s2,b);
28 }
29 
30 int main()
31 {
32     init();
33     int i,j,len=0;
34     memset(c.num,0,sizeof(c.num));
35     for(i=1;i<=a.len;i++)
36         for(j=1;j<=b.len;j++)
37         {
38             int k=i+j-1;
39             c.num[k]+=a.num[i]*b.num[j];
40             while(c.num[k]>=10)
41             {
42                 c.num[k+1]+=c.num[k]/10;
43                 c.num[k]%=10;
44                 k++;
45             }
46             if(k>c.len) c.len=k;
47         }
48     while(c.num[c.len]==0&&c.len>1)
49         c.len--;
50     for(int s=c.len;s>0;s--)
51         cout<<c.num[s];
52     return 0;
53 }

//折叠有点问题就先不折叠了

   (45)高精度加法

 1 #include<iostream>
 2 #include<string>
 3 #include <stdarg.h> 
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<iomanip>
 7 using namespace std;
 8 struct bignum
 9 {
10     int len;
11     int num[1000];
12 }a,b,c;
13 void big(string s,bignum&c)
14 {
15     int h;
16     reverse(s.begin(),s.end());
17     h=s.size();
18     for(int i=0;i<h;i++)
19         c.num[i+1]=int(s[i]-'0');
20     c.len=s.size();
21 }
22 void init()
23 {
24     string s1,s2;
25     cin>>s1>>s2;
26     big(s1,a);
27     big(s2,b);
28 }
29 int main()
30 {
31     init();
32     int len=b.len;
33     if(a.len>b.len) len=a.len;
34     for(int i=1;i<=len;i++)
35     {
36         c.num[i]+=a.num[i]+b.num[i];
37         if(c.num[i]>=10)
38         {
39             c.num[i+1]++;
40             c.num[i]=c.num[i]-10;
41         }
42     }
43     if(c.num[len+1]>0)len++;
44     c.len=len;
45     for(int i=c.len;i>0;i--)
46     cout<<c.num[i];
47     return 0;
48 }

  

  (46)高精度减法

//猴式智减法??

 1 #include<iostream> 
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cstring>
 6 #include<cstdio>
 7 using namespace std;
 8 struct bignum
 9 {
10     int len;
11     int num[1000];
12 }a,b,c;
13 void big(string s,bignum&c)
14 {
15     int h;
16     reverse(s.begin(),s.end());
17     h=s.size();
18     for(int i=0;i<h;i++)
19         c.num[i+1]=int(s[i]-'0');
20     c.len=s.size();
21 }
22 void init()
23 {
24     string s1,s2;
25     cin>>s1>>s2;
26     big(s1,a);
27     big(s2,b);
28 }
29 
30 int main()
31 {
32     init();
33     int i,j,len=0;
34     memset(c.num,0,sizeof(c.num));
35     for(i=1;i<=a.len;i++)
36         for(j=1;j<=b.len;j++)
37         {
38             int k=i+j-1;
39             c.num[k]+=a.num[i]*b.num[j];
40             while(c.num[k]>=10)
41             {
42                 c.num[k+1]+=c.num[k]/10;
43                 c.num[k]%=10;
44                 k++;
45             }
46             if(k>c.len) c.len=k;
47         }
48     while(c.num[c.len]==0&&c.len>1)
49         c.len--;
50     for(int s=c.len;s>0;s--)
51         cout<<c.num[s];
52     return 0;
53 }

  

  (47)高精度除法.....留个坑QAQ

  (48)线段树----区间查询最大值,区间修改

 1 struct shadow
 2 {
 3     int delta;
 4     int maxx;    
 5 }tree[MAXN*4];
 6 int search(int l,int r,int root)
 7 {
 8     int mid,templ,tempr;
 9     if(y<l||x>r)
10         return -9999999999;
11     if(x<=l&&y>=r)
12         return tree[root].maxx;
13     mid=(l+r)/2;
14     int D=tree[root].delta;
15     tree[root*2].delta+=D; tree[root*2+1].maxx+=D;
16     tree[root*2+1].delta+=D; tree[root*2+1].maxx+=D;
17     tree[root].delta=0;
18     templ=search(l,mid,root*2);
19     tempr=search(mid+1,r,root*2+1);
20     return max(templ,tempr);
21 }
22 void updata(int l,int r,int root)
23 {
24     int mid;
25     if(x>r||y<l)
26         return;
27     if(x<=l&&y>=r)
28     {
29         tree[root].maxx++;
30         tree[root].delta++;
31         return;
32     }
33     mid=(l+r)/2;
34     int D=tree[root].delta;tree[root].delta=0;
35     tree[root*2].delta+=D;tree[root*2].maxx+=D;
36     tree[root*2+1].delta+=D;tree[root*2+1].maxx+=D;
37     updata(l,mid,root*2);
38     updata(mid+1,r,root*2+1);
39     tree[root].maxx=max(tree[root*2].maxx,tree[root*2+1].maxx);
40 }
╰( ̄▽ ̄)╭

   (49)树状数组求逆序对

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define MAXN 101000
 7 using namespace std;
 8 int n;
 9 int c[MAXN],a[MAXN];
10 int lowbit(int x)
11 {return x&-x;}
12 void add(int i,int x)
13 {
14     while(i<=MAXN)
15     {
16         c[i]+=x;
17         i+=lowbit(i);
18     }
19 }
20 int sum(int i)
21 {
22     int ans=0;
23     while(i>0)
24     {
25         ans+=c[i];
26         i-=lowbit(i);
27     }
28     return ans;
29 }
30 int main()
31 {
32     //freopen("shadow.in","r",stdin);
33     //freopen("shadow.out","w",stdout);
34     int n;
35     cin>>n;
36     int ans=0;
37     for(int i=1;i<=n;i++)
38     {
39         int x;
40         cin>>x;
41         ans+=i-sum(x+1)-1;
42         //cout<<i<<"-----"<<sum(x-1)<<endl;
43         add(x+1,1);
44     }
45     cout<<ans<<endl;
46     return 0;
47 }
$_$

   (50)欧拉函数(O(n))

 1 void Euler(int x)
 2 {
 3     memset(check,0,sizeof(check));
 4     int l=0;
 5     for(int i=2;i<=x;i++)
 6     {
 7         if(!check[i])
 8         {
 9             prime[++l]=i;
10             phi[i]=i-1;
11         }
12         for(int j=1;j<=l&&prime[j]*i<=x;j++)
13         {
14             check[i*prime[j]]=1;
15             if(i%prime[j])
16                 phi[i*prime[j]]=phi[i]*(prime[j]-1);
17             else
18             {
19                 phi[i*prime[j]]=phi[i]*prime[j];
20                 break;
21             }
22         }
23     }
24 }
(⊙o⊙)

     (51)多重背包//有n个物品和一个容量为C的背包,第i种物品的重量是w[i],价值是v[i],数量为a[i]。求把那些物品放入背包中价值总和最大

 1 void bag()
 2 {
 3     for(int i=1;i<=n;i++)
 4     {
 5         if(w[i]*a[i]>C)
 6         {
 7             for(int c=0;c<=C;c++)
 8                 if(c>=w[i])
 9                     f[c]=max(f[c],f[c-w[i]]+v[i]);
10         }
11         else
12         {
13             int sum=a[i],k=1;
14             while(k<sum)
15             {
16                 for(int c=C;c>=k*w[i];c--)
17                     f[c]=max(f[c],f[c-k*w[i]]+k*v[i]);
18                 sum-=k;
19                 k+=k;
20             }
21             for(int c=C;c>=sum*w[i];c--)
22                 f[c]=max(f[c],f[c-sum*w[i]]+sum*v[i]);
23         }
24     }
25 }
(*@ο@*)

    (52)割点---trajan

 1 void trajan(int x)//----割点-----//
 2 {
 3     low[x]=dfn[x]=++ind;
 4     for(int i=lin[x];i;i=a[i].next)
 5     {
 6         int tmp=a[i].y;
 7         if(!dfn[tmp])
 8         {
 9             trajan(tmp);
10             if(x==h)
11                 son++;
12             else
13             {
14                 low[x]=min(low[x],low[tmp]);
15                 if(low[tmp]>=dfn[x]&&!c[x])
16                 {
17                     ans++;
18                     c[x]=1;
19                 }
20             }
21         }
22         else
23             low[x]=min(low[x],dfn[tmp]);
24     }
25     return ;
26 }
27 void work()
28 {
29     for(int i=1;i<=n;i++)
30         if(!dfn[i])
31         {
32             son=0;
33             h=i;
34             trajan(i);
35             if(son>1&&c[i]==false)
36             {
37                 c[i]=1;
38                 ans++;
39             }
40         }
41     //ans为图中的割点数目,if(c[i])那么i就为一个割点
42 }
(~ ̄▽ ̄)~

  (53)割边---trajan

 1 void trajan(int x,int p=0)//----割边----//
 2 {
 3     dfn[x]=low[x]=++ind;
 4     for(int i=lin[x];i;i=a[i].next)
 5     {
 6         int tmp=a[i].y;
 7         if(!dfn[tmp])
 8         {
 9             trajan(tmp,x);
10             low[x]=min(low[x],dfn[tmp]);
11             if(dfn[x]<low[tmp])
12             {
13                 ans[++l].y=x;
14                 ans[l].next=tmp;
15             }
16         }
17         else if(dfn[tmp]<low[x]&&tmp!=p)
18             low[x]=dfn[tmp];
19     }//ans[]数组中保存的即为割边
20 }
⁽⁽ଘ( ˊᵕˋ )ଓ⁾⁾*

    第十一回更

   作为退役选手的我又回来更新了....//弱弱的补个坑

    (54)线段树----单点修改和区间求值

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define MAXN 110000
 7 using namespace std;
 8 inline int read()
 9 {
10     int x=0,f=1;
11     char ch=getchar();
12     while(ch>'9'||ch<'0')
13     {
14         if(ch=='-')
15             f=-1;
16         ch=getchar();
17     }
18     while(ch>='0'&&ch<='9')
19     {
20         x=x*10+ch-'0';
21         ch=getchar();
22     }
23     return x*f;
24 }
25 struct drt
26 {
27     int v,delta;
28 }tree[MAXN*4];
29 int x,y;
30 void updata(int l,int r,int root)//单点修改
31 {
32     int mid;
33     if(x<l||x>r)
34         return ;
35     if(l==r)
36     {
37         tree[root].v=y;
38         tree[root].delta=y;
39         return ;
40     }
41     mid=(l+r)>>1;
42     int d=tree[root].delta;
43     tree[root<<1].delta+=d;tree[root<<1].v+=d;
44     tree[root<<1|1].delta+=d;tree[root<<1|1].v+=d;
45     tree[root].delta=0;
46     updata(l,mid,root<<1);
47     updata(mid+1,r,root<<1|1);
48     tree[root].v=tree[root<<1].v+tree[root<<1|1].v;
49 }
50 int search(int l,int r,int root)//区间[x,y]求值
51 {
52     int mid,tmpl,tmpr;
53     if(x>r||y<l)
54         return 0;
55     if(x<=l&&y>=r)
56         return tree[root].v;
57     mid=(l+r)>>1;
58     int d=tree[root].delta;
59     tree[root<<1].v+=d;tree[root<<1].delta+=d;
60     tree[root<<1|1].v+=d;tree[root<<1|1].delta+=d;
61     tree[root].delta=0;
62     tmpl=search(l,mid,root<<1);
63     tmpr=search(mid+1,r,root<<1|1);
64     return (tmpl+tmpr);
65 }
66 int main()
67 {
68     memset(tree,0,sizeof(0));
69     int n=read(),w=read();
70     for(int i=1;i<=w;i++)
71     {
72         char ch;
73         cin>>ch;
74         int xx=read(),yy=read();
75         if(ch=='x')//单点修改
76         {
77             x=xx;y=yy;
78             updata(1,n,1);
79         }
80         else
81         {
82             x=xx;y=yy;
83             int ans=search(1,n,1);//求值
84             cout<<ans<<endl;
85         }
86     }
87     return 0;
88 }
o( ̄ヘ ̄o#)

    (55)线段树----区间修改和区间求值

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #define MAXN 101000
  7 #define ll long long
  8 using namespace std;
  9 inline ll read()
 10 {
 11     ll x=0,f=1;
 12     char ch=getchar();
 13     while(ch>'9'||ch<'0')
 14     {
 15         if(ch=='-')
 16             f=-1;
 17         ch=getchar();
 18     }
 19     while(ch>='0'&&ch<='9')
 20     {
 21         x=x*10+ch-'0';
 22         ch=getchar();
 23     }
 24     return x*f;
 25 }
 26 struct drt
 27 {
 28     ll v,d;
 29 }a[MAXN*4];
 30 ll x,y,k;
 31 ll s[MAXN];
 32 void build(ll l,ll r,ll root)
 33 {
 34     ll mid;
 35     if(l==r)
 36     {
 37         a[root].v=s[l];
 38         return ;
 39     }
 40     mid=(l+r)>>1;
 41     a[root].d=0;
 42     build(l,mid,root<<1);
 43     build(mid+1,r,root<<1|1);
 44     a[root].v=a[root<<1].v+a[root<<1|1].v;
 45 }
 46 void f(ll root,ll l,ll r,ll k)
 47 {
 48     a[root].d+=k;
 49     a[root].v+=k*(r-l+1);
 50 }
 51 void updata(ll l,ll r,ll root)
 52 {
 53     ll mid;
 54     if(x>r||y<l)
 55         return ;
 56     if(x<=l&&y>=r)
 57     {
 58         a[root].v+=k*(r-l+1);
 59         a[root].d+=k;
 60         return ;
 61     }
 62     mid=(l+r)>>1;
 63     f(root<<1,l,mid,a[root].d);
 64     f(root<<1|1,mid+1,r,a[root].d);
 65     a[root].d=0;
 66     if(x<=mid) updata(l,mid,root<<1);
 67     if(y>mid) updata(mid+1,r,root<<1|1);
 68     a[root].v=a[root<<1].v+a[root<<1|1].v;
 69 }
 70 ll search(ll l,ll r,ll root)
 71 {
 72     ll mid,sum=0;
 73     if(x>r||y<l)
 74         return 0;
 75     if(x<=l&&y>=r)
 76         return a[root].v;
 77     mid=(l+r)>>1;
 78     int D=a[root].d;
 79     f(root<<1,l,mid,D);
 80     f(root<<1|1,mid+1,r,D);
 81     a[root].d=0;
 82     if(x<=mid) sum+=search(l,mid,root<<1);
 83     if(y>mid) sum+=search(mid+1,r,root<<1|1);
 84      return sum;
 85 }
 86 int main()
 87 {
 88     ll n=read(),m=read();
 89     for(int i=1;i<=n;i++)
 90         s[i]=read();
 91     build(1,n,1);
 92     for(int i=1;i<=m;i++)
 93     {
 94         ll c=read();
 95         if(c==1)
 96         {
 97             x=read();y=read();
 98             k=read();
 99             updata(1,n,1);
100         }
101         else
102         {
103             x=read(),y=read();
104             ll ans=search(1,n,1);
105             cout<<ans<<endl;
106         }
107     }
108     return 0;
109 }
i╮(╯﹏╰)╭

 

 

 

posted @ 2017-09-22 07:20 列車員lcy 阅读(...) 评论(...) 编辑 收藏