T1

//100分做法
我们现在处在第i个位置说明前i个已经匹配好了,那么假设我们下一步走成功了,也就是加的字符和期望的字符串中第i + 1个位置字符相同
那么假设我们下一步没有走成功呢?那么期望值就是拥有相同前缀的位置的期望。什么意思??
//abaa 原
//aba 当前
//匹配失败 abab
这里我们发现其实原字符串中也有ab也就是说我们在当前再走出一个aa还是可以成功完成black_jack的需求的。
那么我们E(i) = 1 + 1/2E(i + 1) + 1/2E(to);
第i个位置的字符要与to相反。因为在KMP中我们能够向下去走是因为我们第i + 1位和第j + 1位能够匹配
//出题人说是会卡log,但是貌似没卡成功所以我还是写的二分查找,并没有写毒瘤KMP
//分割线
code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int MAXN = 2e6 + 17;

struct node
{
    ll x;
    int pos;
}b[MAXN];

ll a1[MAXN],a2[MAXN],p1,p2;
int n;
bool p[MAXN];

bool tmp(node A,node B)
{
    return A.x < B.x;
}

ll f(ll a,ll b,ll p)
{
    ll res = 1;
    while(b > 0)
    {
        if(b % 2)res = res * a % p;
        b >>= 1;
        a = a * a % p;
    }
    return res % p;
}

int sfind(ll x)
{
    int l = 1,r = n;
    while(l < r)
    {
        int mid = (l + r) >> 1;
        if(b[mid].x < x)l = mid + 1;
        else r = mid;
    }
    //cout << b[r].pos << ' ';
    return b[l].pos;
}

int main()
{
    scanf("%d%lld%lld",&n,&p1,&p2);
    ll inv2 = f(2,p1 - 2,p1);
    for(int i = 1;i <= n + 1;i += 1)
    {
        scanf("%lld",&a1[i]);
        b[i].x = a1[i] * inv2 % p1;
        b[i].pos = i - 1;
    }
    for(int i = 1;i <= n + 1;i += 1)
        scanf("%lld",&a2[i]);
    sort(b + 1,b + n + 1,tmp);
    ll x;
    int next;
    for(int i = 1;i <= n;i += 1)
    {
        x = ((a1[i] + p1) - ((1 + a1[i + 1] * inv2) % p1)) % p1;
        //cout << x << ' ';
        next = sfind(x);
        if(!p[next])p[i] = 1;
        else p[i] = 0;
    }
    //cout << endl;
    for(int i = 1;i <= n;i += 1)
    {
        if(p[i])cout << "G";
        else cout << "R";
    }
    cout << endl;
    return 0;
}

T2

这题其实看上去很难实际。。。
首先我们知道对于一棵树中V = E + 1;
那么我现在假设已经知道了答案为n颗树,V1 + V2 + ...Vn = V;E1 + E2 + ...En = E;
俩式相减,式子结果为n。。。。
对于插入边和删除边只需要用map统计一下即可
#include<cstdio>
#include<iostream>
#include<map>
using namespace std;

const int MAXN = 1e5 + 17;

map<int,int>vis;
map<int,map<int,int> >kk;
map<int,int>h;
int co[MAXN],tot,F[MAXN],n,num,m;

int main()
{
    cin >> n;
    int V = 0;
    for(int i = 1,opt,u,v;i <= n;i += 1)
    {
        cin >> opt;
        if(opt == 1)
        {
            scanf("%d%d",&u,&v);
            if(!vis[u])vis[u] = ++num;
            if(!vis[v])vis[v] = ++num;
            if(!kk[vis[u]][vis[v]])
            {
                m++;
                kk[vis[u]][vis[v]] = 1;
                kk[vis[v]][vis[u]] = 1;
                if(!h[vis[u]])V++;
                if(!h[vis[v]])V++;
                h[vis[u]]++;
                h[vis[v]]++;
            }
            //cout << vis[u] << ' ' << vis[v] << endl;
        }
        if(opt == 2)
        {
            scanf("%d%d",&u,&v);
            if(kk[vis[u]][vis[v]])
            {
                m--;
                kk[vis[u]][vis[v]] = 0;
                kk[vis[v]][vis[u]] = 0;
                h[vis[u]]--;
                h[vis[v]]--;
                if(!h[vis[u]])V--;
                if(!h[vis[v]])V--;
            }
        }
        if(opt == 3)
        {
            //cout << num << endl;
            //cout << m << endl;
            printf("%d\n",V-m);
        }
    }
    return 0;
}