C
写+调共4.5小时。吐了。最后改了一句话过了但是忘了改了哪句话了。
做法就是缩点后跑dag,纯暴力用bitset优化,加一堆分类讨论,主要还是练一下码力,没啥算法难度。
#include<bits/stdc++.h>
using namespace std ;
const int maxn = 1e5 + 10 ;
const int maxm = 10000 ;
bitset<maxm> pre_A[maxn] ;
bitset<maxm> A[maxn] ;
bitset<maxm> B[maxn] ;
bitset<maxm> ban ;
bitset<maxm> ans ;
int cnt2 ;
void cle()
{
for(int i = 0 ; i < maxn ; i ++)
{
pre_A[i].reset() ;
A[i].reset() ;
B[i].reset() ;
}
ban.reset() ;
ans.reset() ;
}
struct Tarjan
{
int cnt , scc_num , lay ;
vector<int> low , dfn , belong , st , s ;
vector<bool> vis ;
vector<vector<int>> g ;
void init(int n)
{
cnt = scc_num = lay = 0 ;
low.resize(n + 1) ;
dfn.resize(n + 1) ;
belong.resize(n + 1) ;
st.resize(n + 1) ;
s.resize(n + 1) ;
vis.resize(n + 1) ;
g.resize(n + 1) ;
fill(vis.begin() , vis.end() , false) ;
fill(low.begin() , low.end() , 0) ;
fill(dfn.begin() , dfn.end() , 0) ;
for(int i = 1 ; i <= n ; i ++) g[i].clear() ;
}
void add(int u , int v)
{
g[u].push_back(v) ;
}
void dfs(int u)
{
vis[u] = true ;
low[u] = dfn[u] = ++ lay ;
st[++ cnt] = u ;
for(auto v : g[u])
{
if(dfn[v] == 0)
{
dfs(v) ;
low[u] = min(low[u] , low[v]) ;
}
else if(vis[v]) low[u] = min(low[u] , dfn[v]) ;
}
if(dfn[u] == low[u])
{
++ scc_num ;
do
{
belong[st[cnt]] = scc_num ;
vis[st[cnt]] = false ;
cnt -- ;
} while(st[cnt + 1] != u) ;
}
}
void cal(int n)
{
for(int i = 1 ; i <= n ; i ++)
if(dfn[i] == 0) dfs(i) ;
}
void solve()
{
vector<vector<int>> g2(scc_num + 1) ;
map<pair<int , int> , int> mp ;
vector<int> in(scc_num + 1 , 0) ;
for(int i = 1 ; i <= cnt2 ; i ++)
{
for(auto v : g[i])
{
if(belong[v] != belong[i])
{
int t1 = belong[i] ;
int t2 = belong[v] ;
assert(t1 != t2) ;
if(mp.count({t1 , t2})) continue ;
mp[{t1 , t2}] = 1 ;
g2[t1].push_back(t2) ;
in[t2] ++ ;
}
}
}
queue<int> q ;
for(int i = 1 ; i <= scc_num ; i ++)
if(in[i] == 0)
{
pre_A[i] = A[i] ;
ans |= (pre_A[i] & B[i]) ;
q.push(i) ;
}
while(!q.empty())
{
int u = q.front() ;
q.pop() ;
for(auto v : g

本文介绍了一道涉及图论和线段树的数据结构题目,通过对大权值和小权值的不同处理策略,实现对树形结构的有效更新与查询。文章详细展示了使用线段树进行区间更新和查询的操作细节。

296

被折叠的 条评论
为什么被折叠?



