zoukankan      html  css  js  c++  java
  • NOI Online 2020 提高组游记

    NOI Online 2020

    喂,你们都看到了吧,是 NOI Online 哦

    Day1

    既然是线上赛就肯定只有Day1的啦

    开题,网站卡住;卡了好一会儿,登录...卡住...

    开考10分钟后我才看到完整的三道题题面

    看T1,没思路;看T2,没思路;看T3,没思路...

    然后内心就很崩溃

    后来(大概是半小时左右)想到了T2的做法,对于以第i位结尾的逆序对的个数,每次冒泡排序第i位会往前挪一位变成第i-1位,然后逆序对个数同时-1

    那这样的话拿个线段树维护一下,如果i>k且逆序对个数>k的,我们就把这个逆序对个数减掉k后算进来就是k轮后的逆序对个数了

    然后修改的话逆序对个数只会+1或者-1,随便写写就好了。

    总之不难,但是要特判k>=n的情况。我的确特判了,但是出现了下面的让我送命的代码段。

    if(k>=n)printf("%lld
    ",0);
    printf("%lld
    ",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
    ");
    else puts("NO
    ");
    

    别问我为什么测样例的时候没注意到,我也不知道为什么...

    之后还剩半小时看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
    ",0);
    			else printf("%lld
    ",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
    ",ret);
    	}
    }
    
  • 相关阅读:
    2.HTML案例二 头条页面
    1.HTML入门
    33.1.网络编程入门
    32.原子性
    【转】风控中的特征评价指标(一)——IV和WOE
    【转】Python调用C语言动态链接库
    基于蒙特卡洛树搜索(MCTS)的多维可加性指标的异常根因定位
    正则表达式全集
    基于ray的分布式机器学习(二)
    基于ray的分布式机器学习(一)
  • 原文地址:https://www.cnblogs.com/youddjxd/p/12435340.html
Copyright © 2011-2022 走看看