A
看到要去前导0,直接字符串模拟了,倒着的时候从第一个不为0的数字开始计算这个数字大小,加上原来数字即可

#include
using namespace std;
typedef long long ll;
int main(){
   char s[10];
   cin>>s;
   int sum=0;
   for(int i=0;i<strlen(s);i++) sum=sum*10+s[i]-'0';
   int flag=0;
   int a=0;
   for(int i=strlen(s)-1;i>=0;i--){
      if(s[i]!='0'){
         flag=1;
      }
      if(flag){
         a=a*10+s[i]-'0';
      }
   }
   cout<<sum+a<<endl;
   return 0;
}

B
问题:将一些数字取任意个相加能不能拼凑出3600的倍数,就是背包有无解的问题。
两种做法。
第一种:直接bitset优化.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        bitset<3600> q;
        for(int i=1;i<=n;i++){
          int x;cin>>x;
          x%=3600;
          //右端第一部分是说已经有的基础上再加一个x, 第二部分是溢出3600的部分取余
          q |= (q << x) | (q >> (3600-x));
          q[x]=1;//将x添加上去
        }
        if(q[0]) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }

   return 0;
}

感谢评论区hx073269大哥指正 第二种是个假算法 复杂度爆掉了 应该是数据水了。当然有兴趣的可以看下?(狗头
第二种,想一下,如果n≥3600一定有解,为什么?证明如下:
图片说明
如果对于n个sum取余3600后,余数在0到3599之间都有位置,显然有解。
如果在0~3599有的位置没有,说明至少存在两个位置的sum%3600后的值一样,那么区间的一段就是3600的倍数。得证。
所以n≥3600 直接输出YES
否则跑个背包判断有无解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        vector<int> a(n+1);
        for(int i=1;i<=n;i++) cin>>a[i];
        if(n>=3600) cout<<"YES"<<endl;
        else
        {
            vector<vector<int>> dp(n+1,vector<int>(3600));
            dp[0][0]=1;
            for(int i=0;i<n;i++){
                for(int j=0;j<3600;j++){
                    if(dp[i][j]){
                        dp[i+1][j]+=dp[i][j];
                        dp[i+1][(j+a[i+1])%3600]+=dp[i][j];
                    }
                }
            }
            if(dp[n][0]>1) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
    }

   return 0;
}

C
判断l到r之间有多少个完全平方数,然后判断端点l是不是完全平方数即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){

    int n;
    cin>>n;
    while(n--)
    {
        ll l,r;
        cin>>l>>r;
        ll s1=sqrt(l)+0.000001,s2=sqrt(r)+0.000001;
        ll num=s2-s1;
        if(s1*s1==l) num++;
        cout<<num<<endl;
    }
    return 0;
}

D
考虑开一个二维数组cnt[n][3]
cnt[i][0]表示i受到的波及次数,
cnt[i][1]表示i对儿子节点的波及次数
cnt[i][2]表示i对孙子节点的波及次数

那么对于每次询问,i肯定对i的儿子和孙子造成了波及,所以cnt[i][1]++,cnt[i][2]++
那么往上考虑,i也对他父亲和爷爷造成了波及所有 cnt[f[i]][0]++,cnt[f[f[i]][0]++
还有一点要注意,i本身和i的同父亲的兄弟也会收到波及,那么这里我们要怎么加呢?直接加到i的父亲节点对儿子节点的波及即可,也就是cnt[f[i]][1]++,这样就同时加入了i本身和他兄弟受到的影响
那么对于每个点i,受到的波及次数就是cnt[1][0]+cnt[f[i]][1]+cnt[f[f[i]][2]
即自身收到子节点的波及次数+父亲对自己的波及次数+爷爷对自己的波及次数

所以dfs求出每个点的父亲后按照上述过程模拟即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1<<20;
vector<int>e[maxn];
int cnt[maxn][3];///自己、儿子、孙子
int f[maxn];
void dfs(int x,int fa){
    f[x]=fa;
    for(auto it:e[x]){
        if(it==fa) continue;
         dfs(it,x);
    }
}
int main(){
    ios::sync_with_stdio(0);
   int n,m;cin>>n>>m;
    for(int i=1;i<n;i++){
        int a,b;cin>>a>>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    dfs(1,0);
    f[0]=maxn-1;
    while(m--){
        int a;cin>>a;
        cnt[a][1]++,cnt[a][2]++;
        cnt[f[a]][1]++,cnt[f[a]][0]++;
        cnt[f[f[a]]][0]++;
        cout<<cnt[a][0]+cnt[f[a]][1]+cnt[f[f[a]]][2]<<endl;
    }
   return 0;
}

E
E题中的式子其实就是斐波那契数列的几何意义
图片说明
其实就是问n是不是斐波那契数,是的话输出它的阶乘在m进制下有多少个0,质因数分解完事。
不是的话,就是问1~13皇后有多少种分布方式。
懒得写了。。(其实是太菜了) 还是补了一下

枚举m的质因子i,然后去看x!中有多少个i,我们只需要取最小即可。13皇后?表打出来即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[]={-1, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712};
ll inf=1e18;
ll f[5005];
int main(){

    int cnt;
    f[1]=f[2]=1;
    for(cnt=3;;cnt++){
        f[cnt]=f[cnt-1]+f[cnt-2];
        if(f[cnt]>=inf) break;
    }
    ll x,m;cin>>x>>m;
    int flag=0;
    for(int i=1;i<=cnt;i++) {
        if(f[i]==x){
            flag=1;
            break;
        }
    }
    if(flag){
        ll ans=1e18;
        for(int i=2;i*i<=m;i++){
            if(m%i==0){
                ll num=0;
                while(m%i==0) m/=i,num++;
                ll num1=0;
                ll y=x;
                while(y) num1+=y/i,y/=i;
                ans=min(ans,num1/num);
            }
        }
        if(m!=1) {
            ll num=0;
            while(x) num+=x/m,x/=m;
            ans=min(ans,num);
        }
        cout<<ans<<endl;
    }
    else cout<<a[x%min(13ll,m)+1];
    return 0;
}