A lot of people suffer A + B problem

来源:互联网 发布:手机低头族数据 编辑:程序博客网 时间:2024/05/16 14:05

Problem Description

Calculate a+b.

Input

Two integer a,b (0<=a,b<=10).

Output

Output a+b.

Example Input

1 2

Example Output

3

//*************The shortest AC code:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>int main(){    int a,b;    scanf("%d%d",&a,&b);    printf("%d",a+b);    return 0;}//*************个人的 High precision pressure(高精度压位):
#include <cstdio>  #include <cstring>  #include <cstdlib>  #include <iostream>  #define p 8#define carry 100000000using namespace std;  const int Maxn=50001;  char s1[Maxn],s2[Maxn];  int a[Maxn],b[Maxn],ans[Maxn];  int change(char s[],int n[])   {      char temp[Maxn];       int len=strlen(s+1),cur=0;      while(len/p)    {          strncpy(temp,s+len-p+1,p);        n[++cur]=atoi(temp);         len-=p;    }      if(len)    {        memset(temp,0,sizeof(temp));          strncpy(temp,s+1,len);          n[++cur]=atoi(temp);       }      return cur;}  int add(int a[],int b[],int c[],int l1,int l2)  {      int x=0,l3=max(l1,l2);      for(int i=1;i<=l3;i++)    {          c[i]=a[i]+b[i]+x;          x=c[i]/carry;        c[i]%=carry;      }      while(x>0){c[++l3]=x%10;x/=10;}      return l3;}  void print(int a[],int len)  {       printf("%d",a[len]);    for(int i=len-1;i>=1;i--)printf("%0*d",p,a[i]);    printf("\n");  }  int main()  {    scanf("%s%s",s1+1,s2+1);    int la=change(s1,a);    int lb=change(s2,b);    int len=add(a,b,ans,la,lb);        print(ans,len);}  //另外几份题解
//作者: 洛谷的 Treeloveswater 大神orz Link-Cut Tree解法:

#include<iostream>#include<cstring>#include<cstdio>#include<cstring>using namespace std;struct node {    int data,rev,sum;    node *son[2],*pre;    bool judge();    bool isroot();    void pushdown();    void update();    void setson(node *child,int lr);}lct[233];int top,a,b;node *getnew(int x){    node *now=lct+ ++top;    now->data=x;    now->pre=now->son[1]=now->son[0]=lct;    now->sum=0;    now->rev=0;    return now;}bool node::judge(){return pre->son[1]==this;}bool node::isroot(){    if(pre==lct)return true;    return !(pre->son[1]==this||pre->son[0]==this);}void node::pushdown(){    if(this==lct||!rev)return;    swap(son[0],son[1]);    son[0]->rev^=1;    son[1]->rev^=1;    rev=0;}void node::update(){sum=son[1]->sum+son[0]->sum+data;}void node::setson(node *child,int lr){    this->pushdown();    child->pre=this;    son[lr]=child;    this->update();}void rotate(node *now){    node *father=now->pre,*grandfa=father->pre;    if(!father->isroot()) grandfa->pushdown();    father->pushdown();now->pushdown();    int lr=now->judge();    father->setson(now->son[lr^1],lr);    if(father->isroot()) now->pre=grandfa;    else grandfa->setson(now,father->judge());    now->setson(father,lr^1);    father->update();now->update();    if(grandfa!=lct) grandfa->update();}void splay(node *now){    if(now->isroot())return;    for(;!now->isroot();rotate(now))    if(!now->pre->isroot())    now->judge()==now->pre->judge()?rotate(now->pre):rotate(now);}node *access(node *now){    node *last=lct;    for(;now!=lct;last=now,now=now->pre)    {        splay(now);        now->setson(last,1);    }    return last;}void changeroot(node *now){    access(now)->rev^=1;    splay(now);}void connect(node *x,node *y){    changeroot(x);    x->pre=y;    access(x);}void cut(node *x,node *y){    changeroot(x);    access(y);    splay(x);    x->pushdown();    x->son[1]=y->pre=lct;    x->update();}int query(node *x,node *y){    changeroot(x);    node *now=access(y);    return now->sum;}int main(){    scanf("%d%d",&a,&b);    node *A=getnew(a);    node *B=getnew(b);    //连边 Link        connect(A,B);    //断边 Cut        cut(A,B);    //再连边orz Link again        connect(A,B);    printf("%d\n",query(A,B));     return 0;}

//作者: 洛谷的 SW_Wind 大神orz Splay解法:

//一颗资瓷区间加、区间翻转、区间求和的Splay#include <bits/stdc++.h>#define ll long long#define N 100000using namespace std;int sz[N], rev[N], tag[N], sum[N], ch[N][2], fa[N], val[N];int n, m, rt, x;void push_up(int x){    sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;    sum[x] = sum[ch[x][1]] + sum[ch[x][0]] + val[x];}void push_down(int x){    if(rev[x]){        swap(ch[x][0], ch[x][1]);        if(ch[x][1]) rev[ch[x][1]] ^= 1;        if(ch[x][0]) rev[ch[x][0]] ^= 1;        rev[x] = 0;    }    if(tag[x]){        if(ch[x][1]) tag[ch[x][1]] += tag[x], sum[ch[x][1]] += tag[x];        if(ch[x][0]) tag[ch[x][0]] += tag[x], sum[ch[x][0]] += tag[x];        tag[x] = 0;    }}void rotate(int x, int &k){    int y = fa[x], z = fa[fa[x]];    int kind = ch[y][1] == x;    if(y == k) k = x;    else ch[z][ch[z][1]==y] = x;    fa[x] = z; fa[y] = x; fa[ch[x][!kind]] = y;    ch[y][kind] = ch[x][!kind]; ch[x][!kind] = y;    push_up(y); push_up(x);}void splay(int x, int &k){    while(x != k){        int y = fa[x], z = fa[fa[x]];        if(y != k) if(ch[y][1] == x ^ ch[z][1] == y) rotate(x, k);        else rotate(y, k);        rotate(x, k);    }}int kth(int x, int k){    push_down(x);    int r = sz[ch[x][0]]+1;    if(k == r) return x;    if(k < r) return kth(ch[x][0], k);    else return kth(ch[x][1], k-r);}void split(int l, int r){    int x = kth(rt, l), y = kth(rt, r+2);    splay(x, rt); splay(y, ch[rt][1]);}void rever(int l, int r){    split(l, r);    rev[ch[ch[rt][1]][0]] ^= 1;}void add(int l, int r, int v){    split(l, r);    tag[ch[ch[rt][1]][0]] += v;    val[ch[ch[rt][1]][0]] += v;    push_up(ch[ch[rt][1]][0]);}int build(int l, int r, int f){    if(l > r) return 0;    if(l == r){        fa[l] = f;        sz[l] = 1;        return l;    }    int mid = l + r >> 1;    ch[mid][0] = build(l, mid-1, mid);    ch[mid][1] = build(mid+1, r, mid);    fa[mid] = f;    push_up(mid);    return mid;}int asksum(int l, int r){    split(l, r);    return sum[ch[ch[rt][1]][0]];}int main(){    //总共两个数    n = 2;    rt = build(1, n+2, 0);//建树    for(int i = 1; i <= n; i++){        scanf("%d", &x);        add(i, i, x);//区间加    }    rever(1, n);//区间翻转    printf("%d\n", asksum(1, n));//区间求和    return 0;}

//作者: 洛谷的 周何 大神orz Floyd解法:

#include <cstdio>const int N=5,oo=1023741823;int f[N][N];inline int mn(int a,int b){    return a<b?a:b;}void floyd() {//floyd模板    for (int k=1; k<=N; k++)         for (int i=1; i<=N; i++) if (i==k) continue;        else for (int j=1; j<=N; j++) if (k==j||i==j) continue;        else f[i][j]=mn(f[i][j],f[i][k]+f[k][j]);}int main(){    int a,b;    for (int i=1;i<=N;i++)        for (int j=1;j<=N;j++)            f[i][j]=oo;    scanf ("%d %d",&a,&b);    f[1][2]=a;    f[2][3]=b;//构图,1->2的最短路径是a,2->3的最短路径是b,那么1->3的最短路就是a+b    floyd();    printf ("%d",f[1][3]);//输出    return 0;}

//作者: 洛谷的 Acheing 大神orz 最小生成树解法:

#include <cstdio>#include <algorithm>#define INF 2140000000using namespace std;struct tree{int x,y,t;}a[10];bool cmp(const tree&a,const tree&b){return a.t<b.t;}int f[11],i,j,k,n,m,x,y,t,ans;int root(int x){if (f[x]==x) return x;f[x]=root(f[x]);return f[x];}int main(){    for (i=1;i<=10;i++) f[i]=i;    for (i=1;i<=2;i++){        scanf("%d",&a[i].t);        a[i].x=i+1;a[i].y=1;k++;    }    a[++k].x=1;a[k].y=3,a[k].t=INF;    sort(a+1,a+1+k,cmp);    for (i=1;i<=k;i++){    //    printf("%d %d %d %d\n",k,a[i].x,a[i].y,a[i].t);        x=root(a[i].x);y=root(a[i].y);        if (x!=y) f[x]=y,ans+=a[i].t;     }    printf("%d\n",ans);}

//作者: 洛谷管理员大神 yyy2015c01 ORZ Dijkstra+STL的优先队列优化解法:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cctype>#include <climits>#include <algorithm>#include <map>#include <queue>#include <vector>#include <ctime>#include <string>#include <cstring>using namespace std;const int N=405;struct Edge {    int v,w;};vector<Edge> edge[N*N];int n;int dis[N*N];bool vis[N*N];struct cmp {    bool operator()(int a,int b) {        return dis[a]>dis[b];    }};int Dijkstra(int start,int end){    priority_queue<int,vector<int>,cmp> dijQue;    memset(dis,-1,sizeof(dis));    memset(vis,0,sizeof(vis));    dijQue.push(start);    dis[start]=0;    while(!dijQue.empty()) {        int u=dijQue.top();        dijQue.pop();        vis[u]=0;        if(u==end)            break;        for(int i=0; i<edge[u].size(); i++) {            int v=edge[u][i].v;            if(dis[v]==-1 || dis[v]>dis[u]+edge[u][i].w) {                dis[v]=dis[u]+edge[u][i].w;                if(!vis[v]) {                    vis[v]=true;                    dijQue.push(v);                }            }        }    }    return dis[end];}int main(){    int a,b;    scanf("%d%d",&a,&b);    Edge Qpush;    Qpush.v=1;    Qpush.w=a;    edge[0].push_back(Qpush);    Qpush.v=2;    Qpush.w=b;    edge[1].push_back(Qpush);    printf("%d",Dijkstra(0,2));    return 0;}

//作者: 洛谷 神一般的世界 大神orz 线段树解法:

#include<cstdio>#include<algorithm>#include<cstdlib>#include<cmath>#include<cstring>#include<iostream>using namespace std;struct node{    int val,l,r;};node t[5];int a[5],f[5];int n,m;void init(){    for(int i=1;i<=2;i++){        scanf("%d",&a[i]);    }}void build(int l,int r,int node){//这是棵树    t[node].l=l;t[node].r=r;t[node].val=0;    if(l==r){        f[l]=node;        t[node].val=a[l];        return;    }    int mid=(l+r)>>1;    build(l,mid,node*2);    build(mid+1,r,node*2+1);    t[node].val=t[node*2].val+t[node*2+1].val;}void update(int node){    if(node==1)return;    int fa=node>>1;    t[fa].val=t[fa*2].val+t[fa*2+1].val;    update(fa);}int find(int l,int r,int node){    if(t[node].l==l&&t[node].r==r){        return t[node].val;    }    int sum=0;    int lc=node*2;int rc=lc+1;    if(t[lc].r>=l){        if(t[lc].r>=r){            sum+=find(l,r,lc);        }        else{            sum+=find(l,t[lc].r,lc);        }    }    if(t[rc].l<=r){        if(t[rc].l<=l){            sum+=find(l,r,rc);        }        else{            sum+=find(t[rc].l,r,rc);        }    }    return sum;}int main(){    init();    build(1,2,1);    printf("%d",find(1,2,1));}

//作者: 洛谷的 Linbom 大神orz 字典树解法:

//以每个数字建立字典树

//建立一次查询一次

//spj正负 下面上代码

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>using namespace std;struct node{    int str[26];    int sum;}s[1000];char str1[100];int t=0,tot=0,ss=0;bool f1;void built(){    t=0;    for(int i=0;i<strlen(str1);i++)    {         if(str1[i]=='-'){             f1=true;continue;         }         if(!s[t].str[str1[i]-'0'])         s[t].str[str1[i]-'0']=++tot;         t=s[t].str[str1[i]-'0'];         s[t].sum=str1[i]-'0';    }}int query(){   int t=0;int s1=0;   for(int i=0;i<strlen(str1);i++)   {           if(str1[i]=='-') continue;           if(!s[t].str[str1[i]-'0']) return s1;           t=s[t].str[str1[i]-'0'];           s1=s1*10+s[t].sum;   }   return s1;}int main(){      for(int i=1;i<=2;i++)  {      f1=false;      scanf("%s",str1);    built();    if(f1)      ss-=query();      else ss+=query();  }  printf("%d",ss);  return 0;    }

//作者: 洛谷的 Zyan丶 LCA解法:

建一个有三个节点的树,1为树根,2 3分别是左右儿子。

其中1 2之间的距离为a,2 3之间的距离为b,然后求1 2的LCA,和分别到LCA的距离,加起来就是1->3的最短路

其实就是题目中所求的a+b了

#include<cstdio>                                                  //头文件#define NI 2                                                          //从来不喜欢算log所以一般用常数 不知道算不算坏习惯 因为3个节点 所以log3(当然以2为底)上取整得2struct edge{    int to,next,data;                                              //分别表示边的终点,下一条边的编号和边的权值}e[30];                                                                     //邻接表,点少边少开30是为了浪啊int v[10],d[10],lca[10][NI+1],f[10][NI+1],tot=0;      //数组开到10依然为了浪//数组还解释嘛,v表示第一条边在邻接表中的编号,d是深度,lca[x][i]表示x向上跳2^i的节点,f[x][i]表示x向上跳2^i的距离和void build(int x,int y,int z)                                      //建边{    e[++tot].to=y; e[tot].data=z; e[tot].next=v[x]; v[x]=tot;    e[++tot].to=x; e[tot].data=z; e[tot].next=v[y]; v[y]=tot;}void dfs(int x)                                                        //递归建树{    for(int i=1;i<=NI;i++)                                   //懒,所以常数懒得优化        f[x][i]=f[x][i-1]+f[lca[x][i-1]][i-1],        lca[x][i]=lca[lca[x][i-1]][i-1];                   //建树的同时进行预处理    for(int i=v[x];i;i=e[i].next)                              //遍历每个连接的点    {        int y=e[i].to;        if(lca[x][0]==y) continue;        lca[y][0]=x;                                       //小技巧:lca[x][0]即为x的父亲~~(向上跳2^0=1不就是父节点嘛)        f[y][0]=e[i].data;        d[y]=d[x]+1;        dfs(y);                                            //再以这个节点为根建子树【这里真的用得到嘛??】    }}int ask(int x,int y)                                             //询问,也是关键{                                                                            if(d[x]<d[y]) {int t=x;x=y;y=t;}                  //把x搞成深的点    int k=d[x]-d[y],ans=0;    for(int i=0;i<=NI;i++)        if(k&(1<<i))                                      //若能跳就把x跳一跳            ans+=f[x][i],                              //更新信息            x=lca[x][i];    for(int i=NI;i>=0;i--)                                  //不知道能不能正着循环,好像倒着优,反正记得倒着就好了        if(lca[x][i]!=lca[y][i])                            //如果x跳2^i和y跳2^j没跳到一起就让他们跳            ans+=f[x][i]+f[y][i],            x=lca[x][i],y=lca[y][i];    return ans+f[x][0]+f[y][0];                           //跳到LCA上去(每步跳的时候都要更新信息,而且要在跳之前更新信息哦~)}int main(){    int a,b;    scanf("%d%d",&a,&b);    build(1,2,a);    build(1,3,b);                                                       //分别建1 2、1 3之间的边    dfs(1);                                                                //以1为根建树    printf("%d",ask(2,3));                                         //求解2 3到它们的LCA的距离和并输出}

//作者: 洛谷的 doby

//SPFA解法:

#include<cstdio>using namespace std;int n,m,a,b,op,head[200009],next[200009],dis[200009],len[200009],v[200009],l,r,team[200009],pd[100009],u,v1,e;int lt(int x,int y,int z){    op++,v[op]=y;    next[op]=head[x],head[x]=op,len[op]=z;}int SPFA(int s,int f)//SPFA……{    for(int i=1;i<=200009;i++){dis[i]=999999999;}    l=0,r=1,team[1]=s,pd[s]=1,dis[s]=0;    while(l!=r)    {        l=(l+1)%90000,u=team[l],pd[u]=0,e=head[u];        while(e!=0)        {            v1=v[e];            if(dis[v1]>dis[u]+len[e])            {                dis[v1]=dis[u]+len[e];                if(!pd[v1])                {                    r=(r+1)%90000,                    team[r]=v1,                    pd[v1]=1;                }            }            e=next[e];        }     }    return dis[f];}int main(){    scanf("%d%d",&a,&b);    lt(1,2,a);lt(2,3,b);//1到2为a,2到3为b,1到3即为a+b……    printf("%d",SPFA(1,3));    return 0;}

//作者: 洛谷的 KingLolierl 树状数组解法:

#include<iostream>#include<cstring>using namespace std;int lowbit(int a){    return a&(-a);}int main(){    int n=2,m=1;    int ans[m+1];    int a[n+1],c[n+1],s[n+1];    int o=0;    memset(c,0,sizeof(c));    s[0]=0;    for(int i=1;i<=n;i++)    {        cin>>a[i];        s[i]=s[i-1]+a[i];        c[i]=s[i]-s[i-lowbit(i)];//树状数组创建前缀和优化    }    for(int i=1;i<=m;i++)    {        int q=2;        //if(q==1)        //{(没有更改操作)        //    int x,y;        //    cin>>x>>y;        //    int j=x;        //    while(j<=n)        //    {        //        c[j]+=y;        //        j+=lowbit(j);        //    }        //}        //else        {            int x=1,y=2;//求a[1]+a[2]的和            int s1=0,s2=0,p=x-1;            while(p>0)            {                s1+=c[p];                p-=lowbit(p);//树状数组求和操作,用两个前缀和相减得到区间和            }            p=y;            while(p>0)            {                s2+=c[p];                p-=lowbit(p);            }                o++;            ans[o]=s2-s1;//存储答案        }    }    for(int i=1;i<=o;i++)        cout<<ans[i]<<endl;//输出    return 0;}

好了就这些了,再次对提供A+B问题高端题解的大神表示感谢并在此膜拜orz,如果还有想法欢迎留言,我会补充……

此题涉及了众多算法模板,欢迎算法爱好者前来选购