NOI Online 2020 提升組遊記

NOI Online 2020

喂,大家都看到了吧,是 NOI Online 哦node

Day1

既然是線上賽就確定只有Day1的啦ios

開題,網站卡住;卡了好一下子,登陸...卡住...c++

開考10分鐘後我纔看到完整的三道題題面網站

看T1,沒思路;看T2,沒思路;看T3,沒思路...spa

而後心裏就很崩潰code

後來(大概是半小時左右)想到了T2的作法,對於以第i位結尾的逆序對的個數,每次冒泡排序第i位會往前挪一位變成第i-1位,而後逆序對個數同時-1排序

那這樣的話拿個線段樹維護一下,若是i>k且逆序對個數>k的,咱們就把這個逆序對個數減掉k後算進來就是k輪後的逆序對個數了get

而後修改的話逆序對個數只會+1或者-1,隨便寫寫就行了。string

總之不難,可是要特判k>=n的狀況。個人確特判了,可是出現了下面的讓我送命的代碼段。it

if(k>=n)printf("%lld\n",0);
printf("%lld\n",query(1,1,n,k+1,n)-k*queryb(1,1,n,k+1,n));

沒錯,少了一個else

你覺得這就是結束了嗎?

2h時我開始作T1,只須要按照關係2連個邊,而後再按關係1連邊,看看和能不能變成0就行了。

結果又出現了以下語句。

if(fl)puts("YES\n");
else puts("NO\n");

別問我爲何測樣例的時候沒注意到,我也不知道爲何...

以後還剩半小時看T3...就隨手艹了一個80分的暴力。

你覺得我會得到這最後的80分?不,你錯了,我從新提交文件的時候,新版的尚未保存,我就把舊版的交上去了。

因而考後的估分本來是100+100+80=280的,被我活生生搞成了0+0+0。

可能OI並不適合我。

Day 12

成績出來了,T2沒有k>=n的數據,我得到了100分。

啊?你問T1和T3?掛了就是掛了呀/kk

代碼

T1:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long
int n,m;
struct node{
	int v;
	int nxt;
}edge[200001];
int cnt;
int head[100001];
void add(int a,int c){
	edge[++cnt].v=c;
	edge[cnt].nxt=head[a];
	head[a]=cnt;
}
struct data{
	int id,x,y;
}t[100001];
int f[100001];
int k[100001];
int fa[100001];
int fx,fy;
int tot;
int g;
int s[100001];
int mp[100001];
bool fl,b[100001],r[100001];
bool cmp(data a,data b){
	return a.id>b.id;
}
int father(int a){
	if(fa[a]!=a)fa[a]=father(fa[a]);
	return fa[a];
}
int getfather(int a){
	if(s[a]!=a)s[a]=getfather(s[a]);
	return s[a];
}
int find(int u){
	if(r[u])r[0ll]=1ll;
	b[u]=1ll;
	for(int i=head[u];i;i=edge[i].nxt){
		if(!b[edge[i].v])f[u]=f[u]+find(edge[i].v);
	}
	return k[u]-f[u];
}
void clear(){
	fl=1ll;
	tot=0ll;
	cnt=0ll;
	memset(f,0,sizeof(f));
	memset(k,0,sizeof(k));
	memset(head,0,sizeof(head));
	memset(b,0,sizeof(b));
	memset(r,0,sizeof(r));
	memset(mp,0,sizeof(mp));
}
signed main(){
	int T;
	scanf("%lld",&T);
	while(T){
		clear();
		T--;
		scanf("%lld%lld",&n,&m);
		for(int i=1ll;i<=n;i++){
			scanf("%lld",&f[i]);
		}
		for(int i=1ll;i<=n;i++){
			scanf("%lld",&k[i]);
			fa[i]=i;
		}
		for(int i=1ll;i<=m;i++){
			scanf("%lld%lld%lld",&t[i].id,&t[i].x,&t[i].y);
		}
		sort(t+1ll,t+m+1ll,cmp);
		for(int i=1ll;i<=m;i++){
			if(t[i].id==1)break;
			fx=father(t[i].x);
			fy=father(t[i].y);
			if(fx!=fy){
				fa[fx]=fy;
				f[fy]=f[fy]+f[fx];
				k[fy]=k[fy]+k[fx];
			}
			g=i+1ll;
		}
		for(int i=1ll;i<=n;i++){
			fa[i]=father(i);
			if(fa[i]==i){
				tot++;
				mp[i]=tot;
				s[tot]=tot;
				f[tot]=f[i];
				k[tot]=k[i];
			}
		}
		for(int i=1ll;i<=n;i++)fa[i]=mp[fa[i]];
		for(int i=g;i<=m;i++){
			t[i].x=fa[t[i].x];
			t[i].y=fa[t[i].y];
			if(t[i].x==t[i].y)r[t[i].x]=1ll;
			fx=getfather(t[i].x);
			fy=getfather(t[i].y);
			if(fx!=fy){
				add(t[i].x,t[i].y);
				add(t[i].y,t[i].x);
				s[fx]=fy;
				if(r[fx])r[fy]=1ll;
			}
		}
		for(int i=1ll;i<=tot;i++){
			if(!b[i]){
				r[0ll]=0ll;
				int a=find(i);
				if(r[0ll])a=a%2ll;
				if(a){
					fl=0ll;
					break;
				}
			}
		}
		if(fl)puts("YES");
		else puts("NO");//改過了
	}
}

T2

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int lowbit(int x){return x&-x;}
int bit[200010];
void upd(int x,int val){
	while(x<=n){
		bit[x]+=val;
		x+=lowbit(x);
	}
}
int que(int x){
	int ans=0;
	while(x){
		ans+=bit[x];
		x-=lowbit(x);
	}
	return ans;
}
struct node{
	int pos;
	int val;
}b[200010];
bool operator <(node x,node y){
	return x.val>y.val;
}
int a[200010];
struct nod2{
	int sum;
	int x;
}num[200010];
int t[1000010];
int bbb[1000010];
void update(int o,int l,int r,int x,int val,int type){
	if(x==0)return;
	if(l==r){
		t[o]+=val;
		bbb[o]+=type;
		return;
	}
	int mid=(l+r)/2;
	if(x<=mid)update(o<<1,l,mid,x,val,type);
	else update(o<<1|1,mid+1,r,x,val,type);
	t[o]=t[o<<1]+t[o<<1|1];
	bbb[o]=bbb[o<<1]+bbb[o<<1|1];
}
int query(int o,int l,int r,int L,int R){
	if(L<=l&&r<=R){
		return t[o];
	}
	int ret=0;
	int mid=(l+r)/2;
	if(L<=mid)ret+=query(o<<1,l,mid,L,R);
	if(mid<R)ret+=query(o<<1|1,mid+1,r,L,R);
	return ret;
}
int queryb(int o,int l,int r,int L,int R){
	if(L<=l&&r<=R){
		return bbb[o];
	}
	int ret=0;
	int mid=(l+r)/2;
	if(L<=mid)ret+=queryb(o<<1,l,mid,L,R);
	if(mid<R)ret+=queryb(o<<1|1,mid+1,r,L,R);
	return ret;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%lld",&a[i]);
		b[i].val=a[i],b[i].pos=i;
	}
	sort(b+1,b+1+n);
	for(int i=1;i<=n;++i){
		num[b[i].pos].sum=que(b[i].pos);
		upd(b[i].pos,1);
		num[b[i].pos].x=min(num[b[i].pos].sum,b[i].pos);
		update(1,1,n,num[b[i].pos].x,num[b[i].pos].sum,1);
	}
	for(int i=1;i<=m;++i){
		int opt;
		scanf("%lld",&opt);
		if(opt==1){
			int x;
			scanf("%lld",&x);
			if(a[x]>a[x+1]){
				update(1,1,n,num[x].x,-num[x].sum,-1);
				update(1,1,n,num[x+1].x,-num[x+1].sum,-1);
				swap(num[x],num[x+1]);
				swap(a[x],a[x+1]);
				num[x].sum--;
				num[x].x=min(num[x].sum,x);
				num[x+1].x=min(num[x+1].sum,x+1);
				update(1,1,n,num[x].x,num[x].sum,1);
				update(1,1,n,num[x+1].x,num[x+1].sum,1);
			}
			else if(a[x]==a[x+1])continue;
			else {
				update(1,1,n,num[x].x,-num[x].sum,-1);
				update(1,1,n,num[x+1].x,-num[x+1].sum,-1);
				swap(num[x],num[x+1]);
				swap(a[x],a[x+1]);
				num[x+1].sum++;
				num[x].x=min(num[x].sum,x);
				num[x+1].x=min(num[x+1].sum,x+1);
				update(1,1,n,num[x].x,num[x].sum,1);
				update(1,1,n,num[x+1].x,num[x+1].sum,1);
			}
		}
		else {
			int k;
			scanf("%lld",&k);
			if(k>=n)printf("%lld\n",0);
			else printf("%lld\n",query(1,1,n,k+1,n)-k*queryb(1,1,n,k+1,n));//改過了
		}
	}
}

T3

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
int n,m;
int dp[200001];
int k,ret,p,s;
int gcd(int a,int b){
	if(a%b==0ll)return b;
	return gcd(b,a%b);
}
void find(int a,int b){
	int l,r;
	l=dp[b];
	r=dp[b];
	while(b>a+1ll){
		b--;
		ret=ret+l*dp[b];
		l=dp[b];
		b--;
		ret=ret+r*dp[b];
		r=dp[b];
	}
	if(b==a+1)ret=ret+(l+r)*dp[a];
	else ret=ret+l*r;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1ll;i<=n;i++)scanf("%lld",&dp[i]);
	sort(dp+1ll,dp+n+1ll);
	for(int i=1ll;i<=m;i++){
		scanf("%lld",&k);
		ret=0ll;
		if(k==0ll){
			for(int j=1ll;j<=n;j++){
				ret=ret+dp[j]*dp[j];
			}
		}else{
			p=gcd(n,k);
			s=n/p;
			for(int j=1ll;j<=n;j=j+s){
				find(j,j+s-1ll);
			}
		}
		printf("%lld\n",ret);
	}
}
相關文章
相關標籤/搜索