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);
}
}