D:
将第一种关系建图,求出图上每个点,满足不相邻但可达且不含第二种关系的点的数量,直接建图,注意减数量的时候不要重复即可
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
#define sqr(x) ((x)*(x))
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
#define endl "\n";
void run_case() {
int n, m, k;
cin >> n >> m >> k;
vector<vector<int>> G(n+1, vector<int>());
vector<unordered_set<int>>a(n+1);
vector<int> fa(n+1), siz(n+1), son(n+1), ans(n+1);
for(int i = 0; i < m; ++i) {
int x, y;
cin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
son[x]++, son[y]++;
a[x].insert(y), a[y].insert(x);
}
function<void(int,int,int&)> dfs = [&](int u, int f, int& cnt) {
fa[u] = f; cnt++;
for(auto v: G[u])
if(!fa[v]) dfs(v, f, cnt);
};
for(int i = 1; i <= n; ++i) {
if(!fa[i]) {
int cnt = 0;
dfs(i, i, cnt);
siz[i] = cnt;
}
}
for(int i = 1; i <= n; ++i)
ans[i] = siz[fa[i]] - son[i] - 1;
for(int i = 0; i < k; ++i) {
int x, y;
cin >> x >> y;
if(fa[x] == fa[y] && !a[x].count(y)) ans[x]--, ans[y]--;
}
for(int i = 1; i <= n; ++i) cout << ans[i] << " ";
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(9);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}
F:
在线查询与修改,数据范围5e5,那么对26个字母分别维护一个树状数组即可,难度不大
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
#define sqr(x) ((x)*(x))
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
#define endl "\n";
const int maxn = 5e5+7;
LL a[maxn][26];
void add(int pos, int ch, int val) {
for(;pos<maxn;pos+=lowbit(pos))
a[pos][ch] += val;
}
LL getsum(int pos, int ch) {
LL ret = 0;
for(;pos; pos -= lowbit(pos))
ret += a[pos][ch];
return ret;
}
void run_case() {
int n, q; string s;
cin >> n >> s >> q;
for(int i = 0; i < n; ++i) {
add(i+1, s[i]-'a', 1);
}
while(q--) {
static int type;
cin >> type;
if(type == 1) {
static int pos;
static char ch;
cin >> pos >> ch;
add(pos, s[pos-1]-'a', -1);
s[pos-1] = ch;
add(pos, ch-'a', 1);
} else {
static int l, r;
cin >> l >> r;
int ans = 0;
for(int i = 0; i < 26; ++i)
ans += ((getsum(r, i)-getsum(l-1,i))>0?1:0);
cout << ans << endl;
}
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(9);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}