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;
}
京公网安备 11010502036488号