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; }