20241112【NOIP】模拟
如果上一场是本来都会做,但是因为题没读清楚和智障错误导致挂分后排名低,那么这一场就是纯纯脑瘫,以为题会很难,一点都没有深入思考过,结果暴力一分没挂,但是别人T1T2T3都切了,最后成了小丑🤣👉🤡👈🤣
期望: rk2,实际: rk倒一。除去T3是数据问题让暴力能过70pts,T1和T2就是纯傻逼,而且T3其实也不难/fn/fad
T1
奶龙题。你以为要容斥贡献,实际上每个子矩阵的贡献的期望是独立的,也就是直接 枚举所有子矩阵加上它是黑色/白色的期望即可。
错因:一秒正解没想过,还他妈以为要dp。
T2
奶龙题。你以为是神奇图论,实际上注意到 ,而一遍单源最短路的复杂度是可以 的,所以可以考虑枚举 最为最大值,如果遇到 则不能走这个点,直接这么跑 遍就做完了。注意可以对 去重优化。
T3
不奶龙的题,但是真不难。发现染色操作实际上就是对dfn序列一段区间推平,查询就是到 的前缀和,因为它的颜色集合就是它的所有祖先的颜色集合,可以考虑树状数组差分维护。然后因为是推平所以不用线段树,直接上珂朵莉,对每个颜色暴力维护其覆盖了哪些点。
总结一下,对每个点,用树状数组维护前缀和作为颜色个数,再对每个颜色维护其覆盖了哪些点,用于查询时额外的那个颜色的判断。
代码实现:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll int
#define pb push_back
#define pi pair<ll,ll>
#define fi first
#define se second
#define It set<Chtholly>::iterator
#define in inline
const ll N=300005,M=1919810,mod=1e9+7,inf=2e9;
struct xx{
ll next,to;
}e[2*N];
ll head[2*N],cnt;
void adda(ll x,ll y){
e[++cnt].next=head[x];
e[cnt].to=y;
head[x]=cnt;
}
ll n,m;
ll dfn[N],rk[N],siz[N],t_cnt;
void dfs1(ll u,ll fa){
siz[u]=1;
dfn[u]=++t_cnt,rk[t_cnt]=u;
for(int i=head[u];i;i=e[i].next){
ll v=e[i].to;
if(v==fa) continue;
dfs1(v,u);
siz[u]+=siz[v];
}
}
map <ll,ll> ma;
struct Chtholly{
ll l,r;
mutable ll v;
bool operator <(const Chtholly &b)const{
return l<b.l;
}
};
ll c[N];
ll lowbit(ll x){return x&-x;}
void add(ll x,ll k){
for( ;x<=n;x+=lowbit(x)) c[x]+=k;
}
ll qsum(ll x){
ll ans=0;
for( ;x;x-=lowbit(x)) ans+=c[x];
return ans;
}
struct ODT{
set <Chtholly> s;
in It split(ll now){
It it=s.lower_bound((Chtholly){now,0,0});
if(it!=s.end()&&it->l==now) return it; --it;
if(it->r < now) return s.end();
ll l=it->l,r=it->r,v=it->v;
s.erase(it);
s.insert((Chtholly){l,now-1,v});
return s.insert((Chtholly){now,r,v}).fi;
}
in bool query(ll now){
It it=s.lower_bound((Chtholly){now,0,0});
if(it!=s.end()&&it->l==now) return it->v;
--it; return it->v;
}
in void update(ll l,ll r){
It itr=split(r+1),itl=split(l);
for(It it=itl;it!=itr;++it)
if(!(it->v)) add(it->l,1),add(it->r+1,-1);
s.erase(itl,itr);
s.insert((Chtholly){l,r,1});
}
}s[N];
int main(){
//freopen("yellow.in","r",stdin);
//freopen("ye.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n>>m;
for(int i=1;i<n;++i){
ll a,b;
cin>>a>>b;
adda(a,b),adda(b,a);
}
dfs1(1,0);
ll tot=0;
while(m--){
ll opt,u,x;
cin>>opt>>u>>x;
if(opt==1){
if(!ma[x]){
ma[x]=++tot,x=tot;
s[x].s.insert({1,n,0});
}
else x=ma[x];
s[x].update(dfn[u],dfn[u]+siz[u]-1);
}
else{
if(!ma[x]) cout<<qsum(dfn[u])+1<<'\n';
else cout<<qsum(dfn[u])+(!s[ma[x]].query(dfn[u]))<<'\n';
}
}
return 0;
}/**/
T4
一个优化比较诡异的题,但是40pts是拿到了。
頑張って