NOIP模拟<反思>(36~)
NOIP2023模拟19联测40#
异或连通#
类似于线段树分治,但是可以在
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,m,q,k;
struct asd{
int x,y,c;
}a[N];
int Q[N];
int tr[N*100][2],idx=0;
unordered_map<int,int> rk;
void insert(int x,int p){
int u=0;
for(int i=32;i>=0;i--){
int ch=((x>>i)&1);
if(!tr[u][ch]) tr[u][ch]=++idx;
u=tr[u][ch];
}
rk[p]=u;
}
vector<int> s[N*100];
void updata(int x){
int w=a[x].c;
int u=0;
for(int i=32;i>=0;i--){
int p=((k>>i)&1);
int ch=(((k^w)>>i)&1);
if(p==1 && tr[u][(w>>i)&1]) s[tr[u][(w>>i)&1]].push_back(x);
u=tr[u][ch];
if(!u) break;
}
}
struct qwe{
int x,fx,siz;
}b[N*10];
int top=0;
int fa[N],siz[N];
int get_fa(int x){
if(fa[x]==x) return x;
else return get_fa(fa[x]);
}
int ans=0;
unordered_map<int,int> anss;
void dfs(int x){
int lim=top;
for(int p=0;p<s[x].size();p++){
int i=s[x][p];
int fx=get_fa(a[i].x),fy=get_fa(a[i].y);
if(fx==fy) continue;
if(siz[fx]>siz[fy]){
b[++top]={fy,fx,siz[fx]};
ans=ans-(siz[fx]-1)*siz[fx]/2;
ans=ans-(siz[fy]-1)*siz[fy]/2;
fa[fy]=fx;
siz[fx]+=siz[fy];
ans=ans+(siz[fx]-1)*siz[fx]/2;
}
else{
b[++top]={fx,fy,siz[fy]};
ans=ans-(siz[fx]-1)*siz[fx]/2;
ans=ans-(siz[fy]-1)*siz[fy]/2;
fa[fx]=fy;
siz[fy]+=siz[fx];
ans=ans+(siz[fy]-1)*siz[fy]/2;
}
}
anss[x]=ans;
if(tr[x][0]) dfs(tr[x][0]);
if(tr[x][1]) dfs(tr[x][1]);
while(top>lim){
fa[b[top].x]=b[top].x;
ans-=(siz[b[top].fx]-1)*siz[b[top].fx]/2;
siz[b[top].fx]=b[top].siz;
ans+=(siz[b[top].fx]-1)*siz[b[top].fx]/2+(siz[b[top].x]-1)*siz[b[top].x]/2;
top--;
}
}
signed main(){
// freopen("data.in","r",stdin);
// freopen("cnt.out","w",stdout);
freopen("xor.in","r",stdin);
freopen("xor.out","w",stdout);
scanf("%lld%lld%lld%lld",&n,&m,&q,&k);
for(int i=1;i<=m;i++) scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].c);
for(int i=1;i<=q;i++){
scanf("%lld",&Q[i]);
insert(Q[i],i);
}
for(int i=1;i<=m;i++){
if(a[i].x==a[i].y) continue;
updata(i);
}
for(int i=1;i<=n;i++){
fa[i]=i,siz[i]=1;
}
dfs(1);
for(int i=1;i<=q;i++){
printf("%lld\n",anss[rk[i]]);
}
}
民主投票#
设
那么我们可以二分一个
如果一个点的子树(排除自己)大小大于
我们可以求一个
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int head[N*2],ver[N*2],nex[N*2],tot=0;
void add(int x,int y){
ver[++tot]=y,nex[tot]=head[x],head[x]=tot;
}
int fa[N];
int dp[N];
int lim;
int size[N];
void dfs(int x,int f){
dp[x]=0;
size[x]=1;
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(y==f) continue;
dfs(y,x);
size[x]+=size[y];
dp[x]+=dp[y];
}
if(dp[x]>lim) dp[x]=dp[x]-lim;
else dp[x]=0;
if(x!=1) dp[x]++;
}
bool check(int d){
lim=d;
dfs(1,0);
if(dp[1]==0) return 1;
else return 0;
}
int st[N],top=0;
bool ans[N];
bool flat[N];
void dfs1(int x,int f){
if(flat[x] && dp[x]==2) ans[x]=1;
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(y==f) continue;
if(dp[y]==1) continue;
dfs1(y,x);
}
}
inline int read(){
int x=0;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar()){}
for(;ch>='0' && ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
return x;
}
int main(){
freopen("election.in","r",stdin);
freopen("election.out","w",stdout);
int T;
scanf("%d",&T);
for(int p=1;p<=T;p++){
int n;
n=read();
memset(head,0,sizeof(int)*(n+1));
memset(ans,0,sizeof(bool)*(n+1));
memset(flat,0,sizeof(bool)*(n+1));
tot=0;
for(int i=2;i<=n;++i){
fa[i]=read();
add(i,fa[i]),add(fa[i],i);
}
int l=1,r=sqrt(n)+10;
while(l<r){
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
top=0;
for(int i=1;i<=n;++i){
if(size[i]-1>l) ans[i]=1;
else if(size[i]-1<l) ans[i]=0;
else flat[i]=1;
}
check(l-1);
if(top<=1 && dp[1]==1){
dfs1(1,0);
}
for(int i=1;i<=n;++i){
printf("%d",ans[i]);
}
printf("\n");
}
// cout<<"w ";
}
/*
1
20
1 2 1 3 4 4 3 8 9 8 4 6 11 6 13 12 5 3 19
11110001000000000000
5
7
1 2 3 3 3 4
3
1 1
6
1 2 3 3 1
6
1 1 3 4 4
2
1
1110000
100
110000
101000
10
*/
作者:bloss
出处:https://www.cnblogs.com/jinjiaqioi/p/17837396.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】