2021春季个人赛-7 补题

A.Zero Array

题意: 给定 n n n个数和 q q q个询问,每个询问包含一个操作数,如果操作数为 1 1 1,那么再输入两个数 p , v p,v p,v,使 a [ p ] = v a[p]=v a[p]=v,如果操作数为 2 2 2,输出让这个数组成为 0 0 0数组的最小次数。
零数组的定义:你可以让数组中非零的数减去某个数 x x x,视为一次操作,直到数组全部变为 0 0 0
分析: 只需要计算出数组中有多少个非 0 0 0的、不相同的数即可。数据范围为 1 e 9 1e9 1e9,所以要用 m a p map map,注意 m a p map map不能直接用 s i z e ( ) size() size()

代码:

#include<stdio.h>
#include<map>
using namespace std;
const int N=1e5+5;
int t,n,q,a[N],op,u,v;
int main(){
    
    
	scanf("%d",&t);
	while(t--){
    
    
		int res=0;
		map<int,int> s;
		scanf("%d%d",&n,&q);
		for(int i=1;i<=n;i++){
    
    
			scanf("%d",&a[i]);
			if(a[i]&&!s[a[i]]) res++;
			s[a[i]]++;
		}
		while(q--){
    
    
			scanf("%d",&op);
			if(op==1){
    
    
				scanf("%d%d",&u,&v);
				if(a[u]&&s[a[u]]==1) res--;
				s[a[u]]--;
				if(v&&!s[v]) res++;
				s[v]++;
				a[u]=v;
			}
			else if(op==2){
    
    
				printf("%d\n",res);
			}
		}
	}
}

C.Intersections

题意: 给定 n n n个数 a a a n n n个数 b b b,他们不重复 , a a a数组在上, b b b数组在下,现在从 a a a数组的所有数去配对 b b b数组的所有数,匹配成功(相等)则连一条线,求线段的交点个数。
分析: 求逆序对数量

代码:

#include<stdio.h>
#include<string.h>
const int N=1e5+5;
int t,n,a[N],b[N],tmp[N],x;
long long int res;
void merge_sort(int l,int r){
    
    
    if(l>=r) return ;
    int mid=l+r>>1;
    merge_sort(l,mid);
    merge_sort(mid+1,r);
    int i=l,j=mid+1,k=l;
    while(i<=mid&&j<=r){
    
    
        if(a[i]<=a[j]) tmp[k++]=a[i++];
        else{
    
    
            tmp[k++]=a[j++];
            res+=(mid-i+1);
        }
    }
    while(i<=mid) tmp[k++]=a[i++];
    while(j<=r) tmp[k++]=a[j++];
    for(i=l;i<=r;i++) a[i]=tmp[i];
}
int main(){
    
    
    scanf("%d",&t);
    while(t--){
    
    
        res=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
    
    
            scanf("%d",&x);
            b[x]=i;
        }
        for(int i=1;i<=n;i++){
    
    
            scanf("%d",&x);
            a[i]=b[x];
        }
        merge_sort(1,n);
        printf("%lld\n",res);
    }
}

猜你喜欢

转载自blog.csdn.net/messywind/article/details/114950570