F:
签到题,ifelse一下就行了。。。。我写复杂了。。。。。。。

#include<bits/stdc++.h>
using namespace std;

void solved(){
    string s1,s2;
    cin>>s1>>s2;
    if(s1 == "elephant" && s2 == "tiger"){
        cout<<"tiangou yiwusuoyou"<<endl;return ;
    }else if(s2 == "elephant" && s1 == "tiger"){
        cout<<"tiangou txdy"<<endl;return ;
    }

    if(s1 == "tiger" && s2 == "cat"){
        cout<<"tiangou yiwusuoyou"<<endl;return ;
    }else if(s2 == "tiger" && s1 == "cat"){
        cout<<"tiangou txdy"<<endl;return ;
    }

    if(s1 == "cat" && s2 == "mouse"){
        cout<<"tiangou yiwusuoyou"<<endl;return ;
    }else if(s2 == "cat" && s1 == "mouse"){
        cout<<"tiangou txdy"<<endl;return ;
    }
    if(s1 == "mouse" && s2 == "elephant"){
        cout<<"tiangou yiwusuoyou"<<endl;return ;
    }else if(s2 == "mouse" && s1 == "elephant"){
        cout<<"tiangou txdy"<<endl;return ;
    }
    cout<<"tiangou yiwusuoyou"<<endl;return ;
}
int main(){
    solved();
    return 0;
} 

G:
签到题,贪心选择要画的时间最少的科目,排序一下,然后一个一个去选就行了。(要开ll才行)
代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e6 + 10;
typedef long long int ll;
ll a[maxn];
void solved(){
    ll n,m;scanf("%lld%lld",&n,&m);
    for(ll i = 1; i <= n; i++)scanf("%lld",&a[i]);
    sort(a + 1,a + 1 + n);
    ll ans = 0;
    for(ll i = 1; i <= n; i++){
        if(m >= a[i]){
            m-=a[i];
            ans++;
        }else break;
    }
    printf("%lld\n",ans);
}
int main(){
    solved();
    return 0;
} 

B:
问题可以简化为:给你一些数,满足这些数最大值与最小值差<=k,并长度最长。
为了方便处理,我们先排序,然后枚举每一个数的起始位置,然后二分出它最大值位置(满足差<=k),然后用他们的长度更新答案。
代码

#include<bits/stdc++.h>
using namespace std;

typedef long long int ll;
const int maxn = 2e5 + 10;
ll a[maxn],dis[maxn];
void solved(){
    int t;
    for(scanf("%d",&t);t;t--){
        ll n,k;cin>>n>>k;
        for(int i = 1; i <= n; i++)cin>>a[i];
        sort(a + 1,a + 1 + n);
        int ans = 0;
        for(int i = 1; i <= n; i++){
            int v = k + a[i];
            int pos = lower_bound(a + 1,a + 1 + n,v) - a;
            if(a[pos] == v){
                ans = max(ans,pos - i + 1);
            }else{
                ans = max(ans,pos - i);
            }
        } 
        cout<<ans<<endl;
    }
}
int main(){
    solved();
    return 0;
} 

H:
并查集的裸题了。。不过太久没写并查集导致很多细节没处理好。思路很简单,先将c=1的a,b并在同一个集合,然后检查c=0,如果发现a,b在同一个集合就会产生矛盾。cin超时要用scanf,由于每次读入两个点,所以maxn要开两倍,a,b<=1e9,所以还需要离散化一下,大概就是这些坑了。
代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e6 + 7;
typedef long long int ll;
struct node{
    int a,b,c;
    node(){}
    node(int a,int b,int c):a(a),b(b),c(c){};
}ans[maxn];
int res[maxn << 1];
int f[maxn << 1];
int find(int x){
    return f[x] == x? x : f[x] = find(f[x]);
}
void solved(){
    int t;
    for(scanf("%d",&t);t;t--){
        int n; scanf("%d",&n);
        int cnt = 0;
        for(int i = 1; i  <= n * 2 ; i++)f[i] = i;
        for(int i = 1; i <= n; i++){
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            res[++cnt] = x;
            res[++cnt] = y;
            ans[i] = {x,y,z};
        }
        sort(res + 1,res + 1 + cnt);
        int len = unique(res + 1,res + 1 + cnt) - (res + 1);
        bool flag = true;
        for(int i = 1; i <= n; i++){
            int u = ans[i].a;
            int v = ans[i].b;
            u = lower_bound(res + 1, res + 1 + len,u) - res;
            v = lower_bound(res + 1, res + 1 + len,v) - res;
            if(ans[i].c == 1){
                int fa = find(u);
                int fb = find(v);
                if(fa != fb)f[fa] = fb;
            }else{
                if(find(u) == find(v))flag = false;
            }
        }
        if(flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}
int main(){
    solved();
    return 0;
}

D:
区间修改,区间求和,所以需要用到前缀和与差分,由于是二维的,所以前缀和与差分也需要二维的,可以先对所有区间修改差分一下,然后求一个和,得出每个数原来的值,再求一次前缀和实现O(1)区间和查询。
代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 3e3 + 10;
typedef long long int ll;
ll a[maxn][maxn];
void solved(){
    int n,m,k,q;
    scanf("%d%d%d%d",&n,&m,&k,&q);
    while(k--){
        ll x1,x2,y1,y2;scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
        a[x1][y1]++;
        a[x2 + 1][y2 + 1]++;
        a[x1][y2 + 1]--;
        a[x2 + 1][y1]--;
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            a[i][j] += a[i][j - 1];
        }
    }
    for(int i = 1; i <= m; i++){
        for(int j = 1; j <= n; j++){
            a[i][j] += a[i - 1][j];
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            a[i][j] += a[i - 1][j];
        }
    }
    for(int i = 1; i <= m; i++){
        for(int j = 1; j <= n; j++){
            a[i][j] += a[i][j - 1];
        }
    }
    for(int i = 1; i <= q; i++){
        ll x1,x2,y1,y2;scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
        cout<<a[x2][y2] + a[x1 -  1][y1 - 1] - a[x1 - 1][y2] - a[x2][y1 - 1]<<endl;
    }
}
int main(){
    solved();
    return 0;
} 

J题
sum1求aj的前缀和,sum2求aj^2的前缀和,将公式展开直接O(n)就可以做完了。
图片说明
不过取模有亿点点麻烦,我是把所有能取的地方全部取了才过的,还是减法取模的时候要+mod才行,防止产生负数
代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 5e5 + 10; 
typedef long long int ll;
ll mod = 1e9 + 7;
ll a[maxn];
ll sum1[maxn],sum2[maxn];
void solved(){
    int n;scanf("%d",&n);
    for(int i = 1; i <= n; i++){
        scanf("%lld",&a[i]);
        sum1[i] = (sum1[i - 1] + a[i]) % mod;
        sum2[i] = (sum2[i - 1] + a[i] * a[i] % mod) %mod; 
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++){
        ans += (((n - i) * a[i] % mod * a[i] % mod) %mod - (2 * a[i] % mod * (sum1[n] - sum1[i] + mod) %mod) %mod + (sum2[n] - sum2[i] + mod)%mod)%mod; 
    }
    printf("%lld\n",ans%mod);
}
int main(){
    solved();
    return 0;
} 

C题
题意就是要你包围住这个联通块。
你可以想象一个大矩形,我们要把外面的包起来,里面的不要包,并且边界没有#,所以我们可以直接从起点(1,1)bfs,把那个矩形外围全部标记一下,矩形里面的不用管,然后遍历一下迷宫如果它是#我们就找他的四个方向,如果满足某个方向已经被标记过,我们我们可以把它改成*。
代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e3 + 10;
char s[maxn][maxn];
bool vis[maxn][maxn];
int dir[][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
struct node{
    int x,y;
    node(){}
    node(int a,int b):x(a),y(b){}
};
void bfs(int x,int y){
    queue<node>st;
    st.push(node(x,y));
    while(!st.empty()){
        node cur = st.front();st.pop();
        for(int i = 0 ; i < 4; i++){
            int fx = cur.x + dir[i][0];
            int fy = cur.y + dir[i][1];
            if(fx < 1 || fy < 1 || fx > n || fy > m)continue;
            if(s[fx][fy] != '#' && !vis[fx][fy]){
                st.push(node(fx,fy));
                vis[fx][fy] = true;
            }
        }
    } 
}
void solved(){
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            scanf(" %c",&s[i][j]);
    bfs(1,1);        
    //for(int i = 1; i <= n; i++)
    //    for(int j = 1; j <= m; j++)
    //        if(vis[i][j])cout<<i<<" "<<j<<endl;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(s[i][j] == '#'){
                for(int k = 0; k < 4; k++){
                    int fx = i + dir[k][0];
                    int fy = j + dir[k][1];
                    if(vis[fx][fy] && s[fx][fy] == '.'){
                        s[fx][fy] = '*';
                    }
                }
            }
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            printf("%c",s[i][j]);
        }
        cout<<endl;
    }
}
int main(){
    solved();
    return 0;
}