$$ \newcommand{\seq}[2]{{#1}_{1},{#1}_{2},\cdots,{#1}_{#2}} \newcommand{\num}[1]{1,2,\cdots,#1} \newcommand{\stra}[2]{\begin{bmatrix}#1 \\ #2\end{bmatrix}} \newcommand{\strb}[2]{\begin{Bmatrix}#1 \\ #2\end{Bmatrix}} \newcommand{\dw}[1]{\underline{#1}} \newcommand{\up}[1]{\overline{#1}} $$

Codeforces 588

A

\(n^2\) 删点+暴力更新+bfs。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long D;
typedef pair<D,D> P;
const int maxn=7003;
int n,tot[maxn];
P a[maxn];
bool del[maxn];
bitset<maxn> b[maxn];
queue<int> q;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i].second);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i].first);
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		D suma=0;
		for(int j=1;j<=n;j++){
			if(i==j)continue;
			if((a[i].second&a[j].second)==a[i].second)suma+=a[i].first,b[i].set(j),tot[i]++;
		}
		if(!suma)q.push(i);
	}
	while(!q.empty()){
		int u=q.front();
		q.pop();
		if(del[u])continue;
		del[u]=1;
		for(int i=1;i<=n;i++){
			if(!del[i]&&b[i][u]){
				b[i].reset(u);
				if(!--tot[i])q.push(i);
			}
		}
	}
	D ans=0;
	int cnt=0;
	for(int i=1;i<=n;i++)if(!del[i])ans+=a[i].first,cnt++;
	printf("%lld\n",cnt>=2?ans:0);
	return 0;
}

B

一个性质:从根到某个节点的gcd的数量不会超过log个。
因此从上往下更新答案,搞个map启发式合并即可。

C

链表维护一个节点的入边和出边,修改时暴力维护。可以证明复杂度最坏为 \(O(n\sqrt{n})\) (完全图)。 \(O(n\sqrt{n} \log n)\) 无法通过此题。

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=100003;
struct edge{int to,next;}e[maxn<<1];
int head[maxn],cnte;
void add(int u,int v){e[++cnte].to=v,e[cnte].next=head[u],head[u]=cnte;}
int n,m,in[maxn],out[maxn],hi[maxn],ho[maxn],pr[maxn<<1],nx[maxn<<1];
long long ans;
void add(int h[],int u,int i){
	nx[i]=h[u];
	if(h[u])pr[h[u]]=i;
	h[u]=i;
}
void del(int h[],int u,int i){
	if(i==h[u])h[u]=nx[h[u]];
	if(nx[i])pr[nx[i]]=pr[i];
	if(pr[i])nx[pr[i]]=nx[i];
	pr[i]=nx[i]=0;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v),add(v,u);
	}
	for(int u=1;u<=n;u++){
		for(int i=head[u];i;i=e[i].next){
			int v=e[i].to;
			if(u>v)out[u]++,add(ho,u,i);
			else in[u]++,add(hi,u,i);
		}
	}
	for(int u=1;u<=n;u++){
		for(int i=head[u];i;i=e[i].next){
			int v=e[i].to;
			if(u>v)ans+=out[v];
		}
	}
	printf("%lld\n",ans);
	int Q;
	scanf("%d",&Q);
	while(Q--){
		int u;
		scanf("%d",&u);
		ans-=1ll*in[u]*out[u];
		for(int i=hi[u],j;i;i=j){
			j=nx[i];
			int v=e[i].to;
			ans-=1ll*in[v]*out[v];
			del(hi,u,i);
			add(ho,u,i);
			in[u]--,out[u]++;
			i&1?i++:i--;
			del(ho,v,i);
			add(hi,v,i);
			out[v]--,in[v]++;
			ans+=1ll*in[v]*out[v];
		}
		ans+=1ll*in[u]*out[u];
		printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2019-10-03 11:56  chc_1234567890  阅读(104)  评论(0编辑  收藏  举报